xp主题控件透明背景
我在位图上以及对话框的彩色背景上绘制了一些窗口控件。是否有某种可能的方法使窗口控件的背景透明?目前它们显示对话框的默认彩色背景。
示例 - 我尝试粘贴纯蓝色位图,并且两个按钮控件具有明显的默认彩色矩形背景。
I have a few window controls drawn on a bitmap as well as on colored background on a dialog-box. Would there be some possible way to make the window controls' background transparent? Currently they show the default colored background of a dialog-box.
Example - I tried to paste a solid blue bitmap and the two button controls have the noticeable default colored-rectangle background.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通过为 Windows 提供您希望它用来绘制按钮背景的画笔的句柄,可以轻松解决此问题。每当您收到
WM_CTLCOLORBTN
时,请执行此操作按钮的父窗口的消息处理程序中的消息。我模拟了一个小演示应用程序,它并排比较两个不同的按钮。两者都是标准的 Win32
BUTTON
控件,但左侧的一个处理WM_CTLCOLORBTN
消息并指定与窗口背景颜色相同的画笔。您可以立即看到差异 - 按钮矩形周围的浅灰色(或者更准确地说,3D 控件的默认颜色COLOR_3DFACE
)边缘消失了,按钮在自定义背景颜色的衬托下看起来好多了:该效果也适用于启用视觉主题的 Windows XP — 这是同一应用程序的屏幕截图:
以及我用来创建上述效果的代码几乎简单得可笑。如上所述,将其添加到应用程序的主窗口过程 (
MainWndProc
) 中。您无需触摸按钮。但是,请确保您指定的画笔代表与窗口背景颜色完全相同的颜色 - 透明画笔可能无法正常工作。同样,对于图案画笔(还有人使用它们吗?),
始终确保通过调用
DeleteObject
!! 在 C++ 中,您可以通过将CBrush
对象(或等效对象)作为对话框类的成员来完成此操作,这样它就可以自动销毁。在 C 中,您需要处理WM_NCDESTROY
消息并手动删除画笔。另请注意,您不需要需要指定< code>BS_OWNERDRAW style 才能使这个技巧发挥作用。上面的示例使用两个标准按钮控件,仅使用以下窗口样式标志创建:
WS_CHILD
、WS_VISIBLE
和BS_PUSHBUTTON
。当然,如果您的设计比上面的示例更复杂(例如,您的按钮重叠多个背景),您可能必须采用所有者绘制路线。我只是认为这对于像您所描述的那样简单的任务来说有点过分了。
This is easily solved by providing Windows with a handle to whichever brush you want it to use to paint your button's background. You do this whenever you receive the
WM_CTLCOLORBTN
message in the button's parent window's message handler.I mocked up a little demo application that compares two different buttons side-by-side. Both are standard Win32
BUTTON
controls, but the one on the left handles theWM_CTLCOLORBTN
message and specifies a brush with the same color as the window background. You can see the difference immediately—the light gray (or, more precisely, the default color for 3D controls,COLOR_3DFACE
) fringes around the button's rectangle are gone and the button looks much better against the custom background color:The effect also works in Windows XP with visual themes enabled—here's a screenshot of the same app:
And the code that I used to create the above effect is almost ridiculously simple. Add this to your app's main window procedure (
MainWndProc
), as described above. You don't need to touch your buttons.However, make sure that the brush you specify represents exactly the same color as your window's background color—a transparent brush may not work properly. Similarly, for a patterned brush (does anyone use those anymore?), the brush's origin will need to be set to match the background.
Always make sure that you release any brushes that you create by calling
DeleteObject
!! In C++, you would do this by making aCBrush
object (or equivalent) a member of your dialog class so that it would be automatically destroyed. In C, you'd need to handle theWM_NCDESTROY
message and delete the brush manually.Also note that you do not need to specify the
BS_OWNERDRAW
style in order for this trick to work. The example above uses two standard button controls, created using only the following window style flags:WS_CHILD
,WS_VISIBLE
, andBS_PUSHBUTTON
.Of course, if your design is any more complex than the above example (e.g., your buttons overlap multiple backgrounds), you'll probably have to go the owner-draw route, instead. I just think that's overkill for a task as simple as the one you appear to be describing.
我不知道你是否可以制作真正透明的背景,但我的解决方案无论如何可能对你有帮助。我总是通过在主窗口的过程中使用 WM_CTLCOLORBTN 消息来解决这个问题。
假设我们有一个
switch
,我们在其中处理主窗口接收到的消息。其中
hBgColor
是HBRUSH
,例如:正如我之前所说,这并没有真正使控件的背景透明 - 它只是将其设置为指定的颜色。
编辑:抱歉,我以前犯过一个错误。我编写了
LPARAM
而不是LRESULT
。现在是正确的了。I don't know if you can make a truly transparent background, but my solution may help you anyway. I've always solved it by using the WM_CTLCOLORBTN message in the main window's procedure.
Let's assume that we have a
switch
, in which we process the messages received by the main window.where
hBgColor
is anHBRUSH
, for example:As I said before, this doesn't really make the control's background transparent - it just sets it to the specified color.
EDIT: I'm sorry, I've done a mistake before. I've written
LPARAM
instead ofLRESULT
. Now it's correct.