65.9K
CodeProject 正在变化。 阅读更多。
Home

TCX Owner Draw Engine

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.77/5 (3投票s)

1999 年 12 月 2 日

viewsIcon

54305

downloadIcon

1187

一个帮助编写具有文本格式化功能的属主绘图控件的类

Sample Image - TcxOde.gif

在此,我介绍一个类,它有助于编写具有基本(尽管很可爱)文本格式化功能的所有者绘制控件

CTcxOwnerDrawEngine 类本身不是一个控件类,甚至也不是一个 CWnd 派生类。事实上,它的对象充当所有者绘制控件对象的聚合成员。通过实例化一个 CTcxOwnerDrawEngine 作为成员对象,这些控件可以依赖委托,让引擎来处理复杂的绘制和格式操作。

我们所要做的就是将控件的 DrawItem 方法重定向到 CTcxOwnerDrawEngine::DrawItem 方法,并为其提供绘制项数据 (DRAWITEMSTRUCT) 和项的标记文本字符串。

标记的项字符串描述了文本和格式,这与其他标记语法非常相似。当然,它不像 HTML 或富文本格式那样强大。但是,对于基本功能来说,它已经相当不错了。

为了现在就说清楚,以免以后让您失望:在此版本中,不可能混合不同的字体类型或字体大小。但是,您仍然可以更改字体颜色以及粗体、斜体或下划线属性(以任何组合)。

一瞥之下,打开本文的图是TcxOde Demo Application 屏幕的快照,是在输入以下标记项之后拍摄的——您必须逐行输入。

  <0><-><j><#1010>Table<10>
  <#1000><0><|><j>Group A<5><|><j>Group B<10><|>
  <#1000><0><|><-><j>Col X<1><|><-><j>Col 
  Y<2><|><-><j>Col Z<5><|><-><j>
  Col W<6><|><-><j>Col T<10><|>
  <0><|> <i0> <20> Thales <1><|><j><j><#5>10 <#><2><|><#1><b10><#><5><|>---<6><|>---<10><|>
  <0><|> <i0><i1><i2> <20> Ricardo <1><|><j><j><#5>100 <#><2><|><#1><b100><#><5><|>---<6><|>---<10><|>
  <0><|> <i0> <20> Pacheco <1><|><j><j><#5>20 <#><2><|><#1><b20><#><5><|>---<6><|>---<10><|>
  <0><|> <i0><i1> <20> Eloy <1><|><j><j><#5>50 <#><2><|><#1><b50><#><5><|>---<6><|>---<10><|>
  <0><|> <i2> <20> Marcio <1><|><j><j><#5>3 <#><2><|><#1><b3><#><5><|>---<6><|>---<10><|>
  <0><|><1><|><2><|><5><|><6><|><10><|>
  <0><-><|><1><-><|><2><-><|
  ><5><-><|><6><-><|><10><|>
  <0><-><|><#1000><j><j> Total<#> 
  <1><-><j><j><-><#5>11111 <#><2><|>

TcxOde Demo Application 使用 CTcxOdeListBox,这是一个配备了 CTcxOwnerDrawEngine 的 MFC 所有者绘制 CListBox

标签概览

这里描述了每个存在的标签。

  • <#n> - 选择样式

    此标签为后续绘图选择n 样式,其中n 是从 04294967294 的十进制标识符。每种样式都有一个文本颜色和一个字体属性(粗体、斜体、下划线或这些的任意组合)。在此版本中(并且这很可能是最后一个版本),不可能更改字体大小,也不能更改字体类型。

    样式通过 CTcxOwnerDrawEngine::SetStyle 成员函数独立配置。

    我将其设计为使用外部可配置样式,而不是直接使用标签来选择字体属性和文本颜色,因为我认为样式更加抽象。因此,您可以更改一种样式的属性,所有受影响的项都将自动更改,而无需重新格式化并重新插入到控件中。

    所选样式不会在各项之间持续存在。每次引擎开始绘制新项时,它都会重置为默认样式。

    如果样式不存在(未通过 CTcxOwnerDrawEngine::SetStyle 配置),引擎将继续使用当前样式。

    您可以使用稀疏的样式 ID(例如 1015 和 3)。在内部,引擎将它们保存在一个排序的 CArray 中,并使用二分查找(对于此特定目的,其性能优于 CMap,无论是内存还是速度)。

  • <#> - 选择默认样式

    默认样式基本上是为 CTcxOwnerDrawEngine::DrawItem 提供的 DC 的样式。

  • <n> - 制表符

    此标签将当前绘制位置与制表符n 对齐,其中n 是从 04294967294 的十进制标识符。

    好吧,首先,这是一个普通的制表符,但有三个主要区别:

    • 它有一个 ID。因此,您始终知道要将绘制位置前进到哪个制表符。例如,在没有 ID 的制表符列表框中,如果绘制位置已超过所需的制表符(前面的文本太长),它将前进到下一个制表符(如果存在),并且该项将显示未对齐。

    • 同样,它有一个 ID。带标签的制表符的另一个优点是它们只影响引用它们的项。因此,您可能拥有不同的项组,每个组使用一组单独的制表符,而一个组不会干扰另一个组。

    • 引擎会自动调整它们的大小,因此任何两个不同制表符之间的距离始终足以容纳它们之间的任何文本。这使得该标签可用于创建表。

  • <j> 或 <J> - 对齐

    此标签在两个连续的制表符标记之间将对齐方式从左对齐更改为居中,从居中更改为右对齐。

    引擎开始从左侧对齐文本。如果它找到此标签一次,后续输出将居中对齐,如果找到此标签两次或更多次,后续输出将右对齐。

    例如,以下标记的文本项将产生下图的输出。

       Left <j> Center <j> Right
       Just Left
       <j> Just Center
       Left and... <j><j> Right

    Figure 2

    由于输出一次右对齐,额外的对齐标签将不起作用。但是,请注意,制表符标签会将对齐方式重置为左对齐。

  • <in> 或 <In> - 图标标签

    是的,您可以将 CImageList 附加到引擎(CTcxOwnerDrawEngine::AttachImageList)并指示它绘制图标,使用此标签。只需提供图标索引即可。

  • <-> - 底部水平边框

    此标签指示引擎在当前制表符之间绘制一个底部边框(1 像素的水平线),使用当前的样式颜色。

  • <|> - 垂直边框

    此标签指示引擎在当前绘制位置绘制一个垂直边框(1 像素的垂直线)。

  • <bw> 或 <Bw> - 条形

    此标签指示引擎绘制一个宽度为 w 像素的条形。它会将当前绘制位置向右移动 w 像素。条形使用当前样式的文本颜色绘制。

  • << - 小于号

    此标签绘制 '<' 字符。

  • >> - 大于号

    此标签绘制 '>' 字符。

CTcxOwnerDrawEngine 类成员

CTcxOwnerDrawEngine( void )

构造一个 CTcxOwnerDrawEngine 对象。通常将其作为所有者绘制控件对象类的成员构造(例如,请参见演示中的 CTcxOdeListBox)。

~CTcxOwnerDrawEngine( void )

销毁一个 CTcxOwnerDrawEngine 对象。请注意,析构函数不是虚函数。因此,该对象不打算用作基类,而是用作聚合对象。

void SetStyle( DWORD dwStyleId, COLORREF clrText, BOOL bBold, BOOL bItalic, BOOL bUnderline )

设置由 dwStyleId 标识的样式的属性。

CImageList* AttachImageList( CImageList* pImgList )

将 Image List 对象附加到 CTcxOwnerDrawEngine。Image List 对象必须在被分离或 CTcxOwnerDrawEngine 对象被销毁之前不能被销毁。CTcxOwnerDrawEngine 仅引用 Image List 对象,并且对其生命周期没有控制权。该函数返回先前附加的 Image List 对象,或者 NULL,如果没有先前附加任何对象。

CImageList* DetachImageList( void )

分离当前的 Image List 对象。返回刚分离的 Image List 的指针,或者 NULL,如果当前没有 Image List 被附加。

void DrawItem( LPDRAWITEMSTRUCT pDrw, LPCTSTR pszText )

pDrw 给出的所有者绘制项上下文中绘制 pszText 给出的标记文本。

BOOL InvalidateIsRequired( void )

如果最后一次 DrawItem 操作移动了任何制表符指南,则此函数返回 TRUE。它指示多项容器控件(例如列表框)重绘所有其他可见项以反映新的对齐方式。控件可以通过使客户区域无效来做到这一点(参见演示中的 CTcxOdeListBox)。

void DeleteFonts( void )

删除所有缓存的字体。在对象销毁时会自动完成。使用此选项在某些样式被修改时“清理”引擎的缓存。

void DeleteTabs( void )

重置所有制表符指南。在移除项后,使用此选项“清理”引擎的制表符。

int MaxWidth( void )

返回由引擎已绘制的最大项的宽度。所有者控件可以使用此值来调整其水平扩展或滚动条的大小,以便所有项都可以完全可见(参见演示中的 CTcxOdeListBox)。

void SetMinimumWidth( int cx )

设置最小项宽度(以像素为单位)。引擎可能会绘制比这更宽的项,但不会比这更窄。这会强制引擎扩展具有居中和右对齐元素的项,即使该项可以用更少的空间绘制。

TcxOde 演示应用程序的功能

演示应用程序只是一个带有编辑框和 CTcxOdeListBox 的对话框。列表框的骨干是一个 CTcxOwnerDrawEngine 对象。编辑框只是用于在列表框中输入标记的项字符串。所以,只需在编辑框中键入文本并按 <return>。您也可以通过选择一个项并按 <del> 来删除它。该对话框是可调整大小的。

在演示应用程序中,我使用了以下样式 ID 模式:biuC

其中 biu 是字体属性粗体、斜体和下划线的标志。这些标志可以是 1(开启)或 0(关闭)。而 C 是颜色索引,0 为黑色,1 为浅红色,2 为浅绿色,3 为浅蓝色,4 为深红色,5 为深绿色,6 为深蓝色。

因此,像 <#1003> 这样的标签将激活蓝色粗体字体样式。

但请注意,您可以编程任何您想要的组合。

需要包含的文件

要使用 CTcxOwnerDrawEngine,您必须在项目中包含的唯一文件是:

  • TcxOde.h
  • TcxOde.cpp

另一个现成且易于使用的类是 CTcxOdeListBox,尽管它不是本文的重点。您不必使用它就可以使用引擎。这是一个 MFC 所有者绘制列表框。要在对话框中使用它,请在对话框模板中创建一个具有以下属性的所有者绘制列表框:单选固定所有者绘制有字符串。然后,将 CTcxOdeListBox 对象作为 Dialog 类的成员创建,并使用它来子类化列表框。您需要的文件是:

  • TcxOde.h
  • TcxOde.cpp
  • TcxOdeListBox.h
  • TcxOdeListBox.cpp

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.