xp主题控制的透明背景

时间:2010-12-19 15:21:37

标签: c winapi themes

我在位图上绘制了一些窗口控件,在对话框上绘制了彩色背景。是否有一些可能的方法使窗口控件的背景透明?目前,它们显示对话框的默认彩色背景。

示例 - 我尝试粘贴纯蓝色位图,两个按钮控件具有明显的默认彩色矩形背景。

Dialog window containing two UI-buttons in the middle: 'OK' and 'Cancel'. Though the buttons are a default off-white, most of the inside area of the dialog-box has a shocking bright blue background.

2 个答案:

答案 0 :(得分:6)

通过为Windows提供一个句柄来轻松解决这个问题,这个句柄可以用来绘制按钮背景的画笔。只要您在按钮的父窗口的消息处理程序中收到 WM_CTLCOLORBTN message ,就会执行此操作。

我模拟了一个小型的演示应用程序,它可以并排比较两个不同的按钮。两者都是标准的Win32 BUTTON控件,但左边的控件处理WM_CTLCOLORBTN消息并指定与窗口背景颜色相同的画笔。您可以立即看到差异 - 按钮矩形周围的浅灰色(或者更确切地说,3D控件的默认颜色,COLOR_3DFACE)条纹消失了,按钮看起来比自定义背景色更好:

Transparent Buttons Sample in Windows Vista

此效果也适用于启用了视觉主题的Windows XP - 这是同一个应用程序的屏幕截图:

Transparent Buttons Sample in Windows XP

我用来创建上述效果的代码几乎是非常简单的。将其添加到应用程序的主窗口过程(MainWndProc),如上所述。您无需触摸按钮。

HBRUSH hButtonBackColor = NULL;

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch(msg)
   {
      case WM_CTLCOLORBTN:
      {
         if (!hButtonBackColor)
         {
            // Create the brush, if it hasn't already been created.
            // (You can use any type of brush here; this is just an example.)
            hButtonBackColor = GetSysColorBrush(COLOR_3DDKSHADOW);
         }
         return (LRESULT)hButtonBackColor;
      }

      // ...
   }
}

但是,请确保您指定的画笔表示与窗口背景颜色完全相同的颜色 - 透明画笔可能无法正常工作。同样,对于带图案的画笔(有人再使用它们吗?),brush's origin需要设置为与背景相匹配。

始终确保通过调用DeleteObject释放您创建的任何画笔!! 在C ++中,您可以通过创建CBrush对象(或等效对象)来完成此操作对话框类的成员,以便它自动销毁。在C中,您需要处理WM_NCDESTROY消息并手动删除画笔。

另请注意,需要指定BS_OWNERDRAW style才能使此技巧生效。上面的示例使用两个标准按钮控件,仅使用以下窗口样式标志创建:WS_CHILDWS_VISIBLEBS_PUSHBUTTON

当然,如果你的设计比上面的例子复杂(例如,你的按钮重叠多个背景),你可能不得不采用所有者绘制路线。我认为这对于一个像你似乎要描述的那个简单的任务来说太过分了。

答案 1 :(得分:0)

我不知道你是否可以建立一个真正透明的背景,但无论如何我的解决方案可能对你有帮助。我总是通过在主窗口的程序中使用WM_CTLCOLORBTN消息来解决它 假设我们有一个switch,我们在其中处理主窗口收到的消息。

case WM_CTLCOLORBTN:
    return (LRESULT)hBgColor;
break;

其中hBgColorHBRUSH,例如:

HBRUSH hBgColor=CreateSolidBrush(RGB(0, 0, 255));

正如我之前所说,这并没有真正使控件的背景透明 - 它只是将其设置为指定的颜色。
编辑:对不起,我以前做错了。我写了LPARAM而不是LRESULT。现在这是正确的。