我正在使用自定义绘制来尝试创建透明 TreeView (目前我正在测试何时启用视觉样式)。
我的 CDDS_PREPAINT
处理程序工作正常,树正确绘制了父级的背景位图。
我尝试添加 CDDS_ITEMPREPAINT
我使用 SetBkColor( ((LPNMCUSTOMDRAW)lParam)->hdc, TRANSPARENT );
的处理程序并返回 CDRF_NEWFONT
,但那失败了。节点以默认的白色背景绘制。
如何使项目的文本背景透明?
谢谢。
最好的问候。
下面是说明性代码片段:
switch( ((LPNMCUSTOMDRAW)lParam)->dwDrawStage )
{
case CDDS_PREPAINT:
{
DrawThemeParentBackground(
((LPNMCUSTOMDRAW)lParam)->hdr.hwndFrom,
((LPNMCUSTOMDRAW)lParam)->hdc,
&((LPNMCUSTOMDRAW)lParam)->rc );
// since tree is in dialog box we need below statement
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, (LONG_PTR)CDRF_NOTIFYITEMDRAW );
return TRUE;
}
break;
case CDDS_ITEMPREPAINT : // how to properly handle this ???
{
SetBkMode( ((LPNMCUSTOMDRAW)lParam)->hdc, TRANSPARENT );
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, (LONG_PTR)CDRF_NEWFONT );
return TRUE;
}
break;
}
最佳答案
不幸的是,如果不自己绘制项目,这并不容易实现,抱歉。
事实证明, TreeView 控件传统上使用 ExtTextOut()
内部函数绘制项目标题。此函数采用显式标志参数,其中值 ETO_OPAQUE
表示“应使用当前背景色填充矩形”。
因为这个选项是作为一个额外的标志传递的,而不是通过查看当前的 GDI 后台模式来确定的,所以你不能使用 SetBkMode()
在自定义绘制处理程序中解决此问题。 DC的背景色属性也不支持alpha channel ,不能直接设置为透明。
自 Common Controls 版本 6.0 和主题窗口装饰以来,这有点不同,但在这种情况下仍然没有用:控件只是调用 DrawThemeBackground()
TVP_TREEITEM
部分,其余部分根据所使用的主题进行处理。例如,我在 Windows 8.1 的默认 Aero 主题中看到有这个条目:
ClassID | PartID | StateID | Property | Value
---------+--------------+--------------+-----------------+--------------
TreeView | TVP_TREEITEM | TREIS_NORMAL | FILLCOLOR:COLOR | 255, 255, 255
那么,有哪些替代方案?
总是有一个选项可以为 CDDS_ITEMPREPAINT
事件返回 CDRF_SKIPDEFAULT
并自己完成所有显示操作。但随后您甚至需要注意绘制线条、[+] 框、选择和焦点矩形以及其他所有内容。
另一种选择可能是将存储在控件中的标题文本留空,然后将其添加到 CDDS_ITEMPOSTPAINT
中 - 即使用 TVM_GETITEMRECT
使用 wParam=TRUE
获取文本矩形并在控件已绘制其他所有内容后在那里绘制真实文本。但是这种方法也失败了,因为即使是空文本,也显然会绘制一些微小的不透明矩形。您需要先删除该工件,然后才继续自己绘制文本。想出一个适用于所有项目状态组合的代码似乎很棘手。
关于c++ - 具有透明文本背景而不是默认白色的 Treeview 节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22879703/