我正在使用纯 Win32 API(无 MFC 或 .NET)开发 Win32 GUI 应用程序。我遇到的问题是使控件显得透明。我提出了一种适用于大多数情况的方法,在 Windows Vista+ 中,我在 WndProc 中执行此操作:
case WM_CTLCOLORSTATIC:
{
SetBkMode((HDC)wParam, TRANSPARENT);
return (INT_PTR)::GetStockObject(NULL_PEN);
}
break;
在 Windows XP 中,我在 WndProc 中执行此操作:
case WM_CTLCOLORSTATIC:
{
HBRUSH hbr = (HBRUSH)DefWindowProc(hDlg, message, wParam, lParam);
::DeleteObject(hbr);
SetBkMode((HDC)wParam, TRANSPARENT);
return (LRESULT)(HBRUSH)(COLOR_WINDOW);
}
现在这适用于大多数控件,但是我在组框控件顶部的标签上获得透明背景,该控件通过文本绘制组框线。我开始着手处理一个仅用于分组框的案例,但我确信这是一个以前必须解决的问题,我不想重新发明轮子。
是否有一种久经考验的方法可以使控件看起来透明?
谢谢, J
最佳答案
要实现透明控制,您必须注意:
- 你真的不能。标准的 Windows 控件只是不支持“透明”绘画。
- 即使你做对了,如果你调整它的大小,对话框也会严重闪烁。
- 如果主题打开或关闭,以及 Windows 版本之间的变化,使控件透明绘制工作的“技巧”往往会有所不同。
通常使控件“透明”的目的是让控件下的位图皮肤显示出来。实现这种透明度的方法是为控件的背景创建位图。然后使用位图中的 CreatePatternBrush
。
这段 DialogProc 代码实现了最简单的蒙皮方法,然后将负责绘制对话框的背景以及支持这种绘制形式的大多数控件:
// _hwnd is the dialogs handle
// _hbrSkin is a pattern brush handle
HWND hwndCtl;
POINT pt;
HDC hdc;
case WM_CTLCOLORDLG:
return (INT_PTR)_hbrSkin;
case WM_CTLCOLORSTATIC:
case WM_CTLCOLORBTN:
hdc = (HDC)wParam;
SetBkMode(hdc,TRANSPARENT); // Ensure that "static" text doesn't use a solid fill
pt.x = 0; pt.y = 0;
MapWindowPoints(hwndCtl,_hwnd,&pt,1);
SetBrushOrgEx(hdc,-pt.x,-pt.y,NULL);
return (INT_PTR)_hbrSkin;
重叠的控件将无法正确绘制,因为一个控件会将其“透明”背景绘制在另一个控件之上。您可以通过以下方式减少闪烁:
- 不允许调整对话框的大小。
- 在对话框中设置 WS_EX_COMPOSITED 样式,但由于 Windows NT 6 DWM 不支持它,从 Vista 开始它基本上没用了。
- 在对话框上设置 WS_CLIPCHILDREN 样式或 WS_CLIPSIBLINGS - 这些样式阻止使用组框和选项卡控件,因为它们依赖于控件重叠。
- 对所有控件进行子类化,使用 WM_PRINTCLIENT 消息将它们绘制到后备缓冲区,然后一次性将准备好的后备缓冲区 blit。努力工作,并非所有控件都支持 WM_PRINTCLIENT。
关于windows - 所有版本的 Windows 上的 Win32 透明控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4430559/