【问题标题】:Treeview control in Win32 API - how to display a single treeview item using different fonts?Win32 API 中的 Treeview 控件 - 如何使用不同的字体显示单个 treeview 项?
【发布时间】:2014-05-21 15:36:36
【问题描述】:

我遇到了一个问题,我需要使用Symbol 字体在树视图项(属于符号字符集的那些)中显示一些字符,而其他字符则使用默认系统字体(Segoi UI 在我的 Windows 7 上)。
自定义绘制允许我们使用不同的字体绘制不同的项目,但我想使用不同的字体绘制相同的项目字符串字体,因为它适用于字符串中的每个字符,如上所述。 所以,我所做的结果并不那么令人愉快。到目前为止,当项目数更多时,在水平滚动上绘制性能是这样的:

  1. 我使用 TVS_NOHSCROLL 样式在树视图控件中禁用了水平滚动(因为我在树视图窗口中使用自己的滚动条控件来处理所有水平滚动)
  2. 我对 treeview 控件进行了子类化,在子类化的 winproc 中,我处理水平滚动通知和鼠标通知(我在其中进行自己的命中测试并发送消息,如 TVM_EXPAND 和 TVM_SELECT 作为鼠标单击/双击的结果)点击)。此外,滚动条范围是根据我的自定义绘制字符串的宽度(所有项目中的最大长度)设置的。
  3. 在收到 CDDS_ITEMPOSTPAINT 后,我使用我自己的字体为项目中的每个字符绘制字符串。

上述方法(为简洁起见,我省略了一些细节)有效,但有一些问题让我在这里发布这个问题并寻找替代方法:

问题:

  1. 我创建的水平滚动条控件托管在树视图窗口底部的树视图控件“内部”。但是,当项目的数量超出树视图客户区域可以垂直容纳的数量时,最后一个可见的树视图项目会被滚动条控件遮挡。这可以通过不使滚动条成为树视图的子级并将其托管在其下方的树视图窗口之外来解决。但我不想这样做,因为滚动条通常应该是树视图的子窗口。

  2. 这是主要的。由于我在每次水平滚动时自己绘制项目,因此水平滚动时的绘制性能非常慢,并且还会导致滚动时闪烁。

任何想法都将不胜感激,因为过去一周我一直在努力解决这个问题,但没有成功。

如果您想查看我采用的方法,我也可以在此处发布相关代码,但我确信应该有更好的方法来解决这个问题,并且一定有其他人会遇到这个问题并解决它在过去。

提前致谢。

【问题讨论】:

  • 你为什么使用符号字体中的字符?你现在还在 1996 年吗?

标签: winapi treeview controls


【解决方案1】:

Custom-draw 让您可以随心所欲地绘制项目。您不限于每个项目使用一种字体。当您收到NM_CUSTOMDRAW 通知时,在为指定项目提供的 HDC 上绘制您想要的任何内容。您可以以一种字体绘制文本片段,以不同字体绘制文本片段等。请务必返回CDRF_SKIPDEFAULT,以便 TreeView 本身不会尝试在项目上绘制任何内容。

【讨论】:

  • 问题在于,如果我返回 CDRF_SKIPDEFAULT,Windows 甚至没有绘制 +/- 按钮(展开/折叠),也没有绘制我希望 Windows 绘制的控件中的缩进线。
【解决方案2】:

@Anurag S Sharma:我试图将其编辑为 Remy 的答案。它不完整,但解决了您的评论/疑虑并回答了这个特别令人烦恼/有用的问题...

问题是,如果我返回 CDRF_SKIPDEFAULT,Windows 甚至没有绘制 +/- 按钮(展开/折叠),也没有绘制我希望 Windows 绘制的控件中的缩进线。 – 阿努拉格 S 夏尔马

要保留线条、按钮和图标,您可以使用 ExcludeClipRect 仅屏蔽文本区域,而不是返回 CDRF_SKIPDEFAULT,而是返回 0,就好像您没有绘制任何内容一样。如果树项的文本为空,则这本身就不是必需的,除了文本的边距将始终由默认处理程序绘制(请注意,Microsoft 的控件并不总是尊重剪切形状,但在这种情况下他们会这样做。 )

要在自定义绘制过程中复制经典的 TreeView 标签样式,您需要执行以下操作:

HTREEITEM item = (HTREEITEM)p->dwItemSpec;
TreeView_GetItemRect(p->hdr.hwndFrom,item,&p->rc,1);                
RECT cr, rc = p->rc; GetClientRect(p->hdr.hwndFrom,&cr);                    
DrawTextW(p->hdc,text,-1,&rc,DT_CALCRECT|DT_NOPREFIX|DT_NOCLIP);
rc.right+=4; rc.bottom+=2; IntersectRect(&rc,&cr,&rc);
ExtTextOutW(p->hdc,rc.left+2,rc.top+1,ETO_CLIPPED|ETO_OPAQUE,&rc,text,wcslen(text),0);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 2020-01-08
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    相关资源
    最近更新 更多