具有透明文本背景而不是默认白色的树视图节点



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

我的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;
}

不幸的是,如果不自己绘制项目,这并不容易实现,对不起。

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

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

由于 Common Controls 版本 6.0 和主题窗口修饰,这有点不同,但在这种情况下仍然没有用:控件仅使用 TVP_TREEITEM 部分调用 DrawThemeBackground(),其余部分根据所使用的主题进行处理。例如,我在 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_GETITEMRECTwParam=TRUE一起使用以获取文本矩形,并在控件已经绘制了其他所有内容后在那里绘制真实文本。但是这种方法也失败了,因为即使对于空文本,显然也会绘制一些微小的不透明矩形。您需要先擦除该工件,然后才能继续自己绘制文本。想出一个适用于所有项目状态组合的代码似乎很棘手。

最新更新