在WINAPI中执行透明按钮的正确方法

在WINAPI中执行透明按钮的正确方法,winapi,Winapi,试图用谷歌搜索,但找不到明确的答案 如何使覆盖WM_PAINT的按钮透明。这样你就可以通过它在所有地方看到形状,除了画东西的地方。同时避免闪烁 我看到了使用SetBkMode(HDC,TRANSPARENT)的示例,使用NULL_笔刷的示例,使用CompatibleDC和BitBlts的示例,但我不太确定哪种方法正确,以及在父窗口上设置WM_CLIPCHILDREN时它的行为。我做的大多数实验也有一些奇怪的行为。在MSDN上根本找不到关于WM_擦除BKGND/WM_CTLCOLOR/WM_PAI

试图用谷歌搜索,但找不到明确的答案

如何使覆盖WM_PAINT的按钮透明。这样你就可以通过它在所有地方看到形状,除了画东西的地方。同时避免闪烁

我看到了使用SetBkMode(HDC,TRANSPARENT)的示例,使用NULL_笔刷的示例,使用CompatibleDC和BitBlts的示例,但我不太确定哪种方法正确,以及在父窗口上设置WM_CLIPCHILDREN时它的行为。我做的大多数实验也有一些奇怪的行为。在MSDN上根本找不到关于WM_擦除BKGND/WM_CTLCOLOR/WM_PAINT/WS_EX_COMPOSITED/WS_CLIPCHILDREN/etc内部关系的好文档


有人知道我在哪里可以读到关于这个主题的所有相关信息吗?

嗯,我从来没有找到任何关于这个主题的权威文档

这只是作为我的随机内存转储,试图让控件在设置动画时,在一个已蒙皮(具有位图背景的正常非客户端区域)、分层(以获得具有下拉阴影效果的自定义非客户端边缘的窗口)或具有扩展Aero Glass(通过DwmExtendFrameIntoClient)效果的窗口上“播放”

  • SetBKMode(…TRANSPARENT)只是确保文本呈现不会用当前的bk颜色填充文本的背景
  • WS_EX_COMPOSITED使windows在父窗口无效时将父窗口和所有子窗口绘制到后台缓冲区,然后绘制后台缓冲区。这是无闪烁的,但NT6.0引入了桌面窗口管理器,它不支持WS_EX_COMPOSITED
  • WS_CLIPCHILDREN防止子窗口和父窗口两次绘制同一区域。但如果您需要使用组框或选项卡控件,则禁止使用
  • 如果子窗口重叠并导致闪烁,WS_剪辑可能很有用。同样,如果您需要使用组框或选项卡控件,则此样式是无用的
  • WS_CLIPCHILDREN的另一个问题是,不能在父窗口widnows过程中绘制背景,而只能依靠空笔刷来显示皮肤。您可以从WM_CTLCOLORxxx消息返回笔刷,强制某些标准控件使用皮肤位图绘制其背景
  • WS_EX_LAYERED是另一种使windows缓冲父窗口的绘制的样式。但是分层窗口绘制程序根本不绘制子窗口,因此您需要通过发送WM_PRINTCLIENT消息来手动绘制子窗口。并非所有控件都支持此消息
  • WPF通过根本不为其按钮创建实际的子窗口来解决缺少后缓冲绘制和alpha支持的问题
对局势的最后看法:

只需稍加努力,您就可以轻松地在大多数标准控件后面获得外观。WS_CLIPCHILDREN,并且在父对象上没有背景绘画将模拟闪烁。处理WM_CTLCOLORxxx以填充控件上的背景

如果您使用组框或TabControls来框接其他控件,则如果使用WS_ClipSplings,则绝对必须获得正确的Z顺序


通过发送控件WM_PRINTCLIENT消息和一些子类化,您可以获得标准控件以在DIBSection上绘制,然后您可以手动(或使用DWM worker函数)修复的alpha通道,然后在分层窗口或带有扩展aero glass的窗口上绘制。这甚至是无闪烁的,但不支持WM_PRINTCLIENT或在WM_PAINT之外频繁更新自身的控件将无法正确显示。

WS_ClipSpilings在您描述的情况下是可以的,只要Z顺序正确。很容易做到。那么,如果设置了WS_CLIPCHILDREN,如何用表单颜色填充按钮的背景呢?WS_CLIPCHILDREN将保留子控件占用的部分未上漆,因此我被卡住了。我需要用我不知道的颜色填充SolidRect…如果您使用的是WS_CLIPCHILDREN,那么您可以通过让控件的父窗口响应大多数标准控件支持的WM_CTLCOLORxxx消息来提供控件的背景。WS_EX_COMPOSITED文档强烈暗示,如果没有WS_EX_COMPOSITED,发送到重叠子窗口的WM_PAINT消息的顺序未定义为从下到上。由于绘制dc的剪辑区域必须通过按顺序处理父窗口上的子控件来确定定义,因此在子控件重叠时,WS_ClipSpiling实际上必须用于获得一致的绘制。我的理解是否正确,您希望窗体窗口上有一个透明按钮?还是在另一个父窗口(例如对话框)中?