[英]Direct2D: Opaque child windows over a transparent parent window
I'd like to create a Direct2D application that has a transparent background on which a few opaque complex controls are placed. 我想创建一个Direct2D应用程序,该应用程序具有透明的背景,上面放置了一些不透明的复杂控件。 The problem can be broken into several sub-problems:
该问题可以分为几个子问题:
Architecture: Should the controls be implemented as child windows? 体系结构:控件应作为子窗口实现吗? I think that this is the correct approach, rather that creating Direct2D polygons that implement a child-window functionality.
我认为这是正确的方法,而不是创建实现子窗口功能的Direct2D多边形。
I tried to implement this by initializing the parent window: 我试图通过初始化父窗口来实现这一点:
SetWindowLong(m_hwnd, GWL_EXSTYLE, GetWindowLong(m_hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(m_hwnd, 0, (255 * 50) / 100, LWA_ALPHA);
And create the child window as WS_CHILD . 并将子窗口创建为WS_CHILD 。 This resulted in a child on which all D2D drowings including background are transparent.
这导致了一个孩子,所有D2D草稿(包括背景)都是透明的。 I could not find a way to make the child opaque.
我找不到使孩子变得不透明的方法。 When I create the child window as WS_POPUP or WS_OVERLAPPED the opacity problem is solved but the child window is located on the desktop unrelated to the parent.
当我将子窗口创建为WS_POPUP或WS_OVERLAPPED时 ,不透明度问题得以解决,但子窗口位于与父窗口无关的桌面上。
Layered Window? 分层窗口? I chose to work with Layered Windows but since I target at VistaSP2 and higher there might be better solutions.
我选择使用分层Windows,但是由于我的目标是VistaSP2及更高版本,因此可能会有更好的解决方案。 I tried the solution offered here but I too failed to implement it.
我尝试了此处提供的解决方案,但我也未能实现。
Do you mean to create a 32-bit-per-pixel window? 您是要创建一个每像素32位的窗口吗? (Sorry for being unable to comment, not enough rep over here)
(很抱歉无法发表评论,此处的代表人数不足)
In that case, you are FORCED to use UpdateLayeredWindow (and a CreateDIBSection call while you initialize), no matter what, every time you finished drawing the scene, after you finished drawing the scene, like: 在这种情况下,无论什么时候,每次完成场景绘制之后,都必须使用UpdateLayeredWindow(以及初始化时调用CreateDIBSection),例如:
// Draw to your D2D1 RenderTarget here
RECT rcWin = {0};
GetWindowRect(hWnd,&rcWin);
POINT ptw = {rcWin.left,rcWin.top};
SIZE pts = {rcWin.right-rcWin.left,rcWin.bottom-rcWin.top};
POINT ptsrc = {0};
HDC ScreenDC = GetDC(0);
UpdateLayeredWindow( hWnd, ScreenDC, &ptw, &pts, MemDC, &ptsrc, 0, &bf, ULW_ALPHA);
ReleaseDC(0,ScreenDC);
About the initialization: 关于初始化:
RECT r = {0};
GetWindowRect(hWnd,&r);
HDC scrDC = GetDC(0);
MemDC = CreateCompatibleDC(scrDC);
ReleaseDC(0,scrDC);
if(!MemDC)
{ FailInit(); }
BITMAPINFO bmi = {0};
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biWidth = r.right-r.left;
bmi.bmiHeader.biHeight = r.bottom-r.top;
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
DIBSectionBitmap = CreateDIBSection(MemDC,&bmi,DIB_RGB_COLORS,0,0,0);
if(!DIBSectionBitmap)
return 0;
OldBmp = (HBITMAP)SelectObject(MemDC,DIBSectionBitmap);
// Now create the HWND D2D1 RenderTarget.
About the freeing of the resources: 关于资源的释放:
// Free the D2D1 RenderTarget here
if(MemDC && OldBmp)
SelectObject(MemDC,OldBmp);
if(DIBSectionBitmap)
DeleteObject(DIBSectionBitmap);
if(MemDC)
DeleteDC(MemDC);
MemDC = 0;
OldBmp = 0;
DIBSectionBitmap = 0;
EDIT: MemDC, OldBmp and DIBSectionBitmap are Per-Window. 编辑:MemDC,OldBmp和DIBSectionBitmap是每个窗口。 MemDC is a HDC.
MemDC是HDC。 OldBmp is a HBITMAP.
OldBmp是一个HBITMAP。 DIBSectionBitmap is a HBITMAP.
DIBSectionBitmap是一个HBITMAP。 At this point you can draw your child windows as if they were part of your very own main window, with a per-pixel alpha precision, but you'll need to handle focusing and messaging on your own.
此时,您可以将子窗口绘制为自己的主窗口的一部分,并具有每像素alpha精度,但是您需要自己处理焦点和消息传递。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.