C ++ GDI + рисование текста в прозрачном многослойном окне - PullRequest
4 голосов
/ 24 января 2011

(неуправляемый C ++) Мне уже удалось нарисовать файлы PNG в прозрачном многослойном окне, которое я могу перетащить на рабочий стол, но теперь моя проблема заключается в рисовании текста в прозрачном многослойном окне

Вот мой код и моя попыткапри рисовании текста посередине важно отметить, что я использую screenDC вместо того, чтобы использовать в сообщениях WM_PAINT

[edit] обновленный код после комментариев, теперь я просто пытаюсь написать текстна растровом изображении до получения версии HBITMAP, которую мне нужно использовать на этот раз, я использую DrawString, потому что textout () не является GDI +, я надеюсь, что DrawString действительно GDI +, но все еще не работает, интересно, что я делаю неправильно

void Draw() // draws a frame on the layered window AND moves it based on x and y
{
    HDC screenDC( NULL ); // grab screen
    HDC sourceDC( CreateCompatibleDC(screenDC) );

    POINT pos = {x,y}; // drawing location
    POINT sourcePos = {0,0}; // top left of image
    SIZE size = {100,100}; // 100x100 image

    BLENDFUNCTION blendFunction = {0};
    HBITMAP bufferBitmap = {0};
    Bitmap* TheBitmap = crnimage; // crnimage was already loaded earlier

    // ------------important part goes here, my attempt at drawing text ------------//

 Gdiplus::Graphics     Gx(TheBitmap);

// Font* myFont =    new Font(sourceDC);
 Font myFont(L"Arial", 16);


 RectF therect;
 therect.Height = 20;
 therect.Width = 180;
 therect.X = 0;
 therect.Y = 0;

 StringFormat format;
 format.SetAlignment(StringAlignmentCenter);
 format.GenericDefault();
 Gdiplus::SolidBrush   GxTextBrush(Gdiplus::Color(255, 255, 0,255));


 WCHAR thetext[] = L"Sample Text";

 int stats = Gx.DrawString(thetext, -1, &myFont, therect, &format, &GxTextBrush);
 if(stats) // DrawString returns nonzero if there is an error
     msgbox(stats); 
 stats = Gx.DrawRectangle(&Pen(Color::Red, 3), therect);
 // the rectangle and text both draw fine now

 // ------------important part goes here, my attempt at drawing text ------------//

    TheBitmap->GetHBITMAP(0, &bufferBitmap);
    HBITMAP oldBmpSelInDC;
    oldBmpSelInDC = (HBITMAP)SelectObject(sourceDC, bufferBitmap);

    // some alpha blending
    blendFunction.BlendOp = AC_SRC_OVER;
    blendFunction.SourceConstantAlpha = wndalpha;
    blendFunction.AlphaFormat = AC_SRC_ALPHA;
    COLORREF colorKey( RGB(255,0,255) );
    DWORD flags( ULW_ALPHA);

    UpdateLayeredWindow(hWnd, screenDC, &pos, & size, sourceDC, &sourcePos,
    colorKey, &blendFunction, flags);

    // release buffered image from memory
    SelectObject(sourceDC, oldBmpSelInDC);
    DeleteDC(sourceDC);
    DeleteObject(bufferBitmap); 

    // finally release the screen
    ReleaseDC(0, screenDC);
}

Я уже два дня пытаюсь написать текст в своем многослойном окне, но из этих попыток я знаю, что есть несколько способов сделать это (к сожалению, я понятия не имею, как именно)

Обычный вариант, который я вижу, это рисование текста на растровом изображении, а затем отображение самого растрового изображения

  1. Использование Gdi + для загрузки растрового изображения
  2. Создание объекта Graphics из растрового изображения
  3. Использование DrawString для записи текста в растровое изображение
  4. Утилизация объекта Graphics
  5. Использование метода сохранения растрового изображения для сохранения результата в файл

Видимо, можно также сделать графический объект из DC, затем нарисовать текст на DC, но снова японятия не имею, как это сделать

1 Ответ

2 голосов
/ 25 января 2011

Общий подход выглядит правильно, но я думаю, что у вас есть некоторые проблемы с вызовом DrawString. Проверьте документацию (особенно образец) на MSDN .

Gx.DrawString(thetext, 4, NULL, therect, NULL,  NULL)

Возможно, нужно указать третий, пятый и шестой параметры (шрифт, формат и кисть). В документации не сказано, что они не являются обязательными. Передача NULL для них, вероятно, приводит к тому, что GDI + воспринимает вызов как запрет.

Второй параметр не должен включать в строку завершающий символ L '\ 0'. Вероятно, безопаснее всего использовать -1, если ваша строка всегда завершается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...