开启视觉样式时如何让Windows原生气球提示框的自定义颜色设置生效
Windows 10/11 下TTM_SETTIPBKCOLOR/TTM_SETTIPTEXTCOLOR失效解决方案
失效根因
Windows Vista及以上版本引入视觉样式体系后,当应用通过manifest指定加载ComCtl32 v6+版本公共控件库时,Tooltip控件的绘制逻辑会由系统视觉样式引擎接管,直接发送TTM_SETTIPBKCOLOR、TTM_SETTIPTEXTCOLOR消息的配置会被默认样式绘制逻辑覆盖,只有在经典绘制模式下才会生效。
下面给出两种可落地的解决方案,优先推荐第一种,改动量最小:
方案1:仅对Tooltip控件禁用视觉样式(最小改动)
无需修改原有颜色设置逻辑,只需要在创建Tooltip控件后调用SetWindowTheme函数关闭该控件的视觉样式即可让原有消息生效:
// 需要引入头文件uxtheme.h,编译时链接uxtheme.lib SetWindowTheme(hwndTooltip, L"", L""); // 原有的颜色设置代码不需要改动,直接调用即可生效 SendMessage(hwndTooltip, TTM_SETTIPBKCOLOR, BackColorValue, 0); SendMessage(hwndTooltip, TTM_SETTIPTEXTCOLOR, ForeColorValue, 0);
该方案只会影响当前Tooltip控件的绘制风格,不会改变应用内其他控件的视觉样式表现,同时兼容Windows 7到Windows 11全版本系统。
方案2:响应NM_CUSTOMDRAW通知自绘(保留视觉样式)
如果需要保留Tooltip的圆角、阴影等视觉样式效果,可通过监听NM_CUSTOMDRAW通知自定义绘制颜色:
- 操作步骤:
- 在Tooltip控件的父窗口消息处理函数中监听
WM_NOTIFY消息 - 当通知发送方为Tooltip控件且通知代码为
NM_CUSTOMDRAW时,在预绘制阶段设置DC的背景色和文字颜色即可
代码示例:
case WM_NOTIFY: { NMHDR* pNMHdr = (NMHDR*)lParam; if (pNMHdr->idFrom == 你的Tooltip控件ID && pNMHdr->code == NM_CUSTOMDRAW) { NMTTCUSTOMDRAW* pDraw = (NMTTCUSTOMDRAW*)pNMHdr; if (pDraw->nmcd.dwDrawStage == CDDS_PREPAINT) { // 设置自定义背景色 SetBkColor(pDraw->nmcd.hdc, 你要设置的背景色值); // 设置自定义文字颜色 SetTextColor(pDraw->nmcd.hdc, 你要设置的文字颜色值); return CDRF_NOTIFYITEMDRAW; } } // 其他WM_NOTIFY处理逻辑 break; }
注意事项
- 两种方案都要求应用在manifest中声明对ComCtl32 v6及以上版本的依赖,否则部分API可能不生效
- 高DPI适配场景下建议搭配DPI相关API获取对应缩放参数,避免绘制内容模糊
内容的提问来源于stack exchange,提问作者Tecman
相关产品推荐
相关产品推荐

