C++ GDI+ Рисование изображения в многослойном окне не работает
Итак, я нашел много примеров кода, руководств и ответов на SO о рисовании изображения в многоуровневом окне. Я пытался использовать чистый HBITMAP
S и WIC любят рисовать, и теперь я нахожусь в GDI+ для рисования (что гораздо проще и, казалось бы, проще в использовании, и до сих пор оно решило множество ошибок, которые были вызваны ошибочным кодом WIC).
Я в настоящее время застрял на UpdateLayeredWindow
, Что бы я ни пытался, я не могу заставить его работать. Прямо сейчас возвращается 87, или ERROR_INVALID_PARAMETER
, Вопрос в том, какой из них неверен? Я в тупике! Приведенный ниже код является решением, отличным от того факта, что UpdateLayeredWindow
отказывается работать.
Что я делаю неправильно?
Вот код, который устанавливает HDC/ растровую информацию / графический объект.
// Create DC
_oGrphInf.canvasHDC = GetDC(_hwndWindow);
// Create drawing 'canvas'
_oGrphInf.lpBits = NULL;
_oGrphInf.bmpCanvas = CreateDIBSection(_oGrphInf.canvasHDC,
&_oGrphInf.bmpWinInformation, DIB_RGB_COLORS,
&_oGrphInf.lpBits, NULL, 0);
// Create graphics object
_oGrphInf.graphics = new Gdiplus::Graphics(_oGrphInf.canvasHDC);
Выше работает нормально - я перехожу через него, и все указатели работают.
А вот метод, который рисует PNG.
void Splash::DrawPNG(PNG* lpPNG, int x, int y)
{
LOGD("Drawing bitmap!");
HDC hdcMem = CreateCompatibleDC(_oGrphInf.canvasHDC);
// Select
HBITMAP bmpOld = (HBITMAP)SelectObject(hdcMem, _oGrphInf.bmpCanvas);
Gdiplus::Color trans(0, 0, 0, 0);
_oGrphInf.graphics->Clear(trans);
_oGrphInf.graphics->DrawImage(lpPNG->GetImage(), x, y);
_oGrphInf.graphics->Flush();
SIZE szSize = {_oGrphInf.bmpWinInformation.bmiHeader.biWidth,
_oGrphInf.bmpWinInformation.bmiHeader.biHeight};
// Setup drawing location
POINT ptLoc = {0, 0};
POINT ptSrc = {0, 0};
// Set up alpha blending
BLENDFUNCTION blend = {0};
blend.BlendOp = AC_SRC_OVER;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
blend.BlendFlags = 0;
// Update
if(UpdateLayeredWindow(_hwndWindow, _oGrphInf.canvasHDC, &ptLoc,
&szSize, hdcMem, &ptSrc,
(COLORREF)RGB(0, 0, 0),
&blend, ULW_ALPHA) == FALSE)
LOGE("Could not update layered window: %u", GetLastError());
// Delete temp objects
SelectObject(hdcMem, bmpOld);
DeleteObject(hdcMem);
DeleteDC(hdcMem);
}
Выдернуть мои волосы! Помогите?
РЕДАКТИРОВАТЬ: я просто решил переписать вызов UpdateLayeredWindow
функция, которая решает проблему с неверным параметром. Вот что я придумал. Тем не менее, это все еще не работает. Что я делаю неправильно?
UpdateLayeredWindow(_hwndWindow, _oGrphInf.canvasHDC,
NULL, NULL, hdcMem, &ptLoc,
RGB(0, 0, 0), &blend, ULW_ALPHA)
1 ответ
Чтобы альфа-информация сохранялась в операциях рисования, вы должны сделать свой объект Graphics на основе объекта Bitmap с поддержкой памяти, а не HDC, и, конечно, ваше Bitmap должно быть в формате с альфа-каналом.
Вам нужно будет использовать этот конструктор растровых изображений: http://msdn.microsoft.com/en-us/library/ms536315%28v=vs.85%29.aspx
Просто дайте ему шаг 0, указатель на биты вашей DIB и PixelFormat32bppPARGB.
Затем используйте Graphics::FromImage для создания вашего объекта Graphics.
Я никогда не использовал UpdateLayeredWindow, поэтому я не могу убедиться, что эта сторона верна.