5

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

我的CDDS_PREPAINT处理程序工作正常,树正确绘制了父级的背景位图。

我试图CDDS_ITEMPREPAINT在我使用SetBkColor( ((LPNMCUSTOMDRAW)lParam)->hdc, TRANSPARENT );和 return的地方添加处理程序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;
}
4

1 回答 1

5

不幸的是,如果不自己绘制物品,这将是不容易的,抱歉。

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

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

由于 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

那么,有哪些替代方案?

始终可以选择返回CDRF_SKIPDEFAULT参加CDDS_ITEMPREPAINT活动并自己进行所有显示操作。但是你需要注意绘制线条、[+] 框、选择和焦点矩形以及其他所有内容。

另一种选择可能是将存储在控件中的标题文本保留为空,然后将其添加CDDS_ITEMPOSTPAINT- 即使用TVM_GETITEMRECTwithwParam=TRUE获取文本矩形并在控件已绘制所有其他内容后在此处绘制真实文本。但是这种方法也失败了,因为即使对于空文本,也显然绘制了一些小的不透明矩形。您需要先擦除该工件,然后才能继续自己绘制文本。想出一个适用于所有项目状态组合的代码似乎很棘手。

于 2014-05-02T00:44:46.110 回答