c++ - 具有透明文本背景而不是默认白色的 Treeview 节点

标签 c++ winapi treeview custom-draw

我正在使用自定义绘制来尝试创建透明 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/

相关文章:

c# - 为什么 TreeView 控件创建空白节点?

Python tkinter 小部件在更改时调整大小

java - 如何在 SWT/Tree 和/或 JFace/TreeViewer 中扩展给定路径?

c++ - 如何声明作为类中任何类型对象的数据成员

c++ - 为什么阅读不是线程安全的?

c++ - GLSL 将颜色数据从片段着色器发送到顶点着色器似乎总是等于 0

c - CryptGenRandom() 是线程安全的吗?

c++ - 将迭代器作为 3 个元素的滑动窗口,可以越过边界(可能使用 Boost)

c++ - WriteConsoleOutputCharacter 使控制台应用程序崩溃

c++ - 在没有窗口的情况下运行 C++ 非托管控制台应用程序(不是批处理文件)