Конечной целью этого является наличие заставки в окнах с прозрачностью, но это не то, что я застрял прямо сейчас.Экран всплеска Windows с использованием GDI +
Чтобы создать прозрачное окно, я сначала пытаюсь объединить заставку и текст в буфер вне экрана с помощью GDI +.
В настоящее время я просто пытаюсь создать буфер и отобразить его в ответ на сообщение «WM_PAINT». На данный момент это не работает; все, что я вижу, это черное окно.
Я полагаю, я понял кое-что касаемо установки целей визуализации в GDI +, а затем делает их (я пытаюсь сделать экран, используя прямой GDI Blit)
Во всяком случае, вот код до сих пор :
//my window initialisation code
void MyWindow::create_hwnd(HINSTANCE instance, const SIZE &dim)
{
DWORD ex_style = WS_EX_LAYERED ; //eventually I'll be making use of this layerd flag
m_hwnd = CreateWindowEx(
ex_style,
szFloatingWindowClass ,
L"",
WS_POPUP ,
0,
0,
dim.cx,
dim.cy,
null,
null,
instance,
null);
m_display_dc = GetDC(NULL);
//This was sanity check test code - just loading a standard HBITMAP and displaying it in WM_PAINT. It worked fine
//HANDLE handle= LoadImage(NULL , L"c:\\test_image2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
m_gdip_offscreen_bm = new Gdiplus::Bitmap(dim.cx, dim.cy);
m_gdi_dc = Gdiplus::Graphics::FromImage(m_gdip_offscreen_bm);//new Gdiplus::Graphics(m_splash_dc);//window_dc ;m_splash_dc
//this draws the conents of my splash screen - this works if I create a GDI+ context for the window, rather than for an offscreen bitmap.
//For all I know, it might actually be working but when I try to display the contents on screen, it shows a black image
draw_all();
//this is just to show that drawing something simple on the offscreen bit map seems to have no effect
Gdiplus::Pen pen(Gdiplus::Color(255, 0, 0, 255));
m_gdi_dc->DrawLine(&pen, 0,0,100,100);
DWORD last_error = GetLastError(); //returns '0' at this stage
}
И вот snipit, который обрабатывает сообщение WM_PAINT:
---8<-----------------------
//Paint message snippit
case WM_PAINT:
{
BITMAP bm;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(vg->m_hwnd, &ps); //get the HWNDs DC
HDC hdcMem = vg->m_gdi_dc->GetHDC(); //get the HDC from our offscreen GDI+ object
unsigned int width = vg->m_gdip_offscreen_bm->GetWidth(); //width and height seem fine at this point
unsigned int height = vg->m_gdip_offscreen_bm->GetHeight();
BitBlt(hdc, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY); //this blits a black rectangle
DWORD last_error = GetLastError(); //this was '0'
vg->m_gdi_dc->ReleaseHDC(hdcMem);
EndPaint(vg->m_hwnd, &ps); //end paint
return 1;
}
---8<-----------------------
Мои извинения за длинный пост. Кто-нибудь знает, что я не совсем понимаю, как вы пишете в буфер вне экрана, используя GDI + (или GDI, если на то пошло), а затем отображать это на экране?
Благодарим вас за чтение.
Я обнаружил, что если я создаю другой контекст GDI + для экрана и нарисую композицию, используя это, он отлично работает. Однако причина, по которой я пыталась использовать GDI-методы, заключалась в том, что я мог бы заставить это работать с ' UpdateLayeredWindow.Мой вопрос о том, как разжечь изображение GDI + с помощью GDI-до сих пор стоит. – Luther
Этот код не будет работать, поскольку сообщения WM_PAINT НЕ отправляются, если в этом окне добавлен стиль WS_EX_LAYERED. Это приводит к тому, что окна только расширяют свою копию оконного растрового изображения Windows, обновляемого UpdateLayeredWindow. –
Спасибо за подсказку Крис. Сейчас я отключил многоуровневый флаг, но у меня все еще не получается рисовать альфа-смешанное изображение. В настоящее время я пытаюсь использовать «AlphaBlend», который, кажется, является заменой fpr BitBlt для рендеринга альфа-смешанных изображений. Пока нет кубиков, он просто устанавливает GetLastError в «ERROR_INVALID_PARAMETER», но не уточняет. Я никогда не буду дружить с Win32 и GDI; они просто не играют хорошо! Альфа-смешивание должно быть тривиальным. – Luther