Treeview节点有透明文本背景而不是默认白色

Alw*_*uff 5 c++ treeview winapi custom-draw

我正在使用自定义绘制来尝试创建透明树视图(现在我正在测试启用视觉样式时).

我的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;
}
Run Code Online (Sandbox Code Playgroud)

Yir*_*kha 5

不幸的是,如果没有自己画出物品,这是不容易的,抱歉.

事实证明树视图控件传统上在ExtTextOut()内部使用函数来绘制项目标题.此函数采用显式标志参数,其中值ETO_OPAQUE表示" 应使用当前背景颜色填充矩形 ".

因为此选项作为额外标志传递,而不是通过查看当前的GDI背景模式来确定,所以您不能SetBkMode()在自定义绘制处理程序中使用它来解决此问题.DC的背景颜色属性也不支持alpha通道,因此不能只设置为透明.

由于公共控件6.0版本和主题窗口装饰,这是一个有点不同,但仍然在这种情况下没有用处:控制只是调用DrawThemeBackground()TVP_TREEITEM部分和其余部分根据正在使用的主题处理.我在Windows 8.1的默认Aero主题中看到有这样的条目:

ClassID  | PartID       | StateID      | Property        | Value
---------+--------------+--------------+-----------------+--------------
TreeView | TVP_TREEITEM | TREIS_NORMAL | FILLCOLOR:COLOR | 255, 255, 255
Run Code Online (Sandbox Code Playgroud)

那么,有哪些替代方案?

总是有返回的选择CDRF_SKIPDEFAULTCDDS_ITEMPREPAINT事件和自己做所有的显示操作.但是你需要处理绘制线条,[+]框,选择和聚焦矩形以及其他所有内容.

另一种选择可能是离开存储在控制空标题的文本,然后将其添加在CDDS_ITEMPOSTPAINT-即使用TVM_GETITEMRECTwParam=TRUE来获取文本矩形,并绘制有真正的文本之后一切已经控制了已经画.但是这种方法也失败了,因为即使对于空文本,也会显示出一些微小的不透明矩形.您需要先擦除该工件,然后再继续绘制文本.提出一个适用于项目状态的所有组合的代码似乎很棘手.