MFC 中的动态透明几何体
Posted
技术标签:
【中文标题】MFC 中的动态透明几何体【英文标题】:Dynamic transparency geometry in MFC 【发布时间】:2020-09-01 16:37:34 【问题描述】:我正在为我的 MFC 应用程序创建一个新的 UI 演练,并希望在演练进行时突出显示某些控件。具体来说,我想让整个窗口变暗,除了我要强调的控件。
我尝试使用SetLayeredWindowAttributes
创建一个部分透明的黑色叠加层,但这并不能让我设置一个子区域完全透明。 UpdateLayeredWindow
可以做到这一点,但我并不急于为需要突出显示的每个控件创建 BMP/PNG 文件。
我可以动态创建透明几何吗?例如,我可以从头开始绘制位图透明度然后将其加载到UpdateLayeredWindow
吗?
我还需要兼容 Windows 7(尽管它支持 EOL)。
跟进: 尝试绘制透明 GDI+ 区域,但不起作用:
void ApplicationDlg::Highlight(const CRect& rect)
CRect wndRect;
GetWindowRect(&wndRect);
Gdiplus::Rect wndRectPlus(wndRect.left, wndRect.top, wndRect.Width(), wndRect.Height());
Gdiplus::Region wndRegion(wndRectPlus);
Gdiplus::Rect controlRectPlus(rect.left, rect.top, rect.Width(), rect.Height());
Gdiplus::Region highlightRegion(controlRectPlus);
wndRegion.Exclude(&highlightRegion);
Gdiplus::SolidBrush transparentBrush(Gdiplus::Color(0, 0, 0, 0));
Gdiplus::SolidBrush darkenBrush(Gdiplus::Color(128, 0, 0, 0));
CDC* pDCScreen = m_WalkthroughDlg.GetDC();
HDC hDC = CreateCompatibleDC(pDCScreen->m_hDC);
HBITMAP hBmp = CreateCompatibleBitmap(hDC, wndRect.Width(), wndRect.Height());
HBITMAP hBmpOld = (HBITMAP)SelectObject(hDC, hBmp);
Gdiplus::Graphics graphics(hDC);
graphics.FillRegion(&darkenBrush, &wndRegion);
graphics.FillRegion(&transparentBrush, &highlightRegion);
BLENDFUNCTION blend = 0;
blend.BlendOp = AC_SRC_OVER;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
SIZE sizeWnd = wndRect.Width(), wndRect.Height();
POINT ptSrc = 0,0;
m_WalkthroughDlg.UpdateLayeredWindow(pDCScreen, NULL, &sizeWnd, CDC::FromHandle(hDC), &ptSrc, NULL, &blend, ULW_ALPHA); // TODO cleanup FromHandle refs
m_WalkthroughDlg.BringWindowToTop();
SelectObject(hDC, hBmpOld);
DeleteObject(hBmp);
DeleteDC(hDC);
【问题讨论】:
【参考方案1】:您可以使用CRgn
类动态创建掩码:https://docs.microsoft.com/en-us/cpp/mfc/reference/crgn-class?view=vs-2019
它允许您组合区域(如果您需要突出显示多个区域)。然后您可以使用FillRgn
函数来更新UpdateLayeredWindow
中使用的hdcSrc
DC。
或者,如果您的高光是矩形的,您可以在 hdcSrc
上绘制矩形。
【讨论】:
尝试使用 GDI+Region
类,因为 GDI CRgn
缺乏透明度。但一定是做错了什么,覆盖窗口没有绘制。
非常感谢您能看一下我更新问题的代码。
您对这个最新代码有什么看法?我对 GDI+ 不熟悉,但如果您以某种方式在此处附加您的项目,可以看看。
窗口完全 100% 透明,尽管验证控件 Rect 比窗口 Rect 小得多。很遗憾,我无法分享该项目。
我真的没有时间创建一个虚拟骨架项目来玩这个。但是,您可以回到原来的解决方案,但不要使用一个深色叠加层,而是创建四个围绕您突出显示的控件:顶部一个,底部一个,每侧两个。以上是关于MFC 中的动态透明几何体的主要内容,如果未能解决你的问题,请参考以下文章