XHtmlTree - 支持HTML、XML、智能复选框以及拖放功能的树形控件






4.97/5 (160投票s)
XHtmlTree 是一个基于 CTreeCtrl 的 MFC 控件,支持 HTML 文本、网页链接、APP: 链接、XML 加载/保存、智能复选框以及拖放功能。
![]() 2007年8月获奖 月度竞赛 |
引言
每个人都熟悉树形控件:每次打开 Windows 资源管理器时,都会看到文件系统层次结构以树形显示。另一种树形控件被一些程序(如安装程序)用于允许您选择要安装的选项。当特定子树的所有选项都被选中时,您会看到一个带有勾号的复选框 ();当子树中没有选项被选中时,子树根旁边的复选框会显示一个未选中的复选框 (
);当子树中只有部分选项被选中时,您会看到所谓的三态复选框 (
)。
令人惊讶的是,MFC 的 CTreeCtrl 中并没有直接支持三态复选框。最接近的方法是为您的树创建一个三态图像列表。虽然这可行,但它无法提供 XP 主题复选框的完整视觉效果,例如鼠标悬停时的热状态外观 ()。
当我研究树形控件以及如何添加三态复选框时,我了解到树形控件(类似于列表控件)可以通过自定义绘制机制,通过许多有用的功能和漂亮的 UI 效果进行增强。这促使我迈出了下一步:为树形项添加 HTML 支持。由于我刚刚完成了我的 XHtmlDraw 文章,所以很容易看出这是如何实现的。
不久我就草拟出了我的新树形控件的需求
![]() |
支持主题的复选框 - 我希望在复选框切换时向父级发送通知消息,并获得完整的主题支持;这意味着支持悬停(热)状态,复选框的绘制应与主题化的 XP 复选框完全相同。当然,在 Vista 上,复选框应该具有 Vista 外观。
|
![]() |
智能复选框 - 这是我开始使用(但并非发明)的一个术语,用于描述选中父项时也会选中该项的所有子项,反之,取消选中子项时,如果其他子项仍被选中,则父项会显示三态复选框。以下是其工作原理的快速演示。
当然,智能复选框是可选的——您可以拥有复选框而无需使用智能复选框。 |
![]() |
HTML - 我想包含 XHtmlDraw 功能,包括对网页链接和 APP: 链接的支持。 |
![]() |
增强的树形导航和状态 - 阅读 Zafir Anjum 的文章 给我带来了改进树形控件编程接口的想法,我还想实现更好的管理功能,例如确定有多少项被选中,一个项有多少子项等等,并在项展开时向父级发送通知消息。 |
![]() |
使用 XML 加载和保存树数据 - 随着 XML 在更多应用程序中被采用,这是一个常见的需求。 |
XHtmlTree 功能
此对话框允许您选择树的数据源。它可以是文本文件或 XML 文件(文件以资源形式存储,详情请参阅我的XResFile 文章)。每种文件类型都有两种选择——一种是完整列表,第二种是每个主节点包含十个项目的部分列表,以便于调试。
点击按钮后,您将看到
以下是主要功能
- 选项复选框允许以各种树范围内的选项显示树——即,它们影响所有项目。
- 显示已选中按钮显示一个无模式对话框,其中显示当前已选中项目的列表。
图像已缩小。 要刷新列表,只需再次单击按钮。
- “查找”按钮显示“查找对话框”
此对话框使用内置的
CXHtmlTree::FindItem()
函数来搜索项目文本。对话框上的一个选项允许您标记所有匹配的项目,您可以使用“显示已选中”对话框进行观察。 - “颜色”按钮显示“颜色对话框”
请注意,背景颜色将设置为整个树形控件的背景(通过
SetBkColor()
)。但是,单个项目可以通过使用SetItemTextBkColor()
或使用 HTML 来独立设置其背景。 - 这些是拖放滚动滚动速度的指示器。
- 这三个按钮允许您切换所有项目的勾选状态、展开所有项目和折叠所有项目。
- 树形控件显示一个已勾选的项目。请注意,其父项(Collies)显示为三态勾选框,表示其子项之一(但不是全部)已勾选。其父项(Herding Dogs)也具有三态勾选框。
- 编辑框包含项目文本,您可以修改它,然后使用更新按钮将新文本写入树项目。
- “树信息”显示整个树的信息。
- “项目信息”显示有关项目的信息 - 无论是当前选定的项目,还是刚刚展开的项目。
- 树形面包屑导航通过使用
GetItemPath()
函数和 XBreadCrumbBar 显示。当您点击活动面包屑时,该树节点将被选中。 - 当从控件接收到通知消息(
TVN_SELCHANGED
、WM_XHTMLTREE_CHECKBOX_CLICKED
和WM_XHTMLTREE_ITEM_EXPANDED
)时,“日志”会显示信息。您可以使用复选框启用或禁用日志。
实现说明
HTML
要查看支持的 HTML 标签的完整列表,包括如何使用网页链接和 APP: 链接,请参阅我的 XHtmlDraw 文章。
颜色和文本属性
以下函数支持项目和树的颜色以及文本属性
函数 | 适用范围 | 描述 |
---|---|---|
COLORREF GetBkColor() | 树形控件 | 获取树的当前背景颜色 |
BOOL GetItemBold(HTREEITEM hItem) | 项 | 获取项的粗体状态(TRUE = 项是粗体) |
COLORREF GetItemTextBkColor(HTREEITEM hItem) | 项 | 获取项目的文本背景颜色 |
COLORREF GetItemTextColor(HTREEITEM hItem) | 项 | 获取项目文本颜色 |
LOGFONT * GetLogfont() | 树形控件 | 获取指向当前 LOGFONT 的指针 |
COLORREF GetTextColor() | 树形控件 | 获取树的当前文本颜色 |
BOOL GetUseLogfont() | 树形控件 | 获取 LOGFONT 的当前状态 (TRUE = 使用指定的 LOGFONT) |
COLORREF SetBkColor(COLORREF rgb) | 树形控件 | 设置树的背景颜色 |
BOOL SetItemBold(HTREEITEM hItem, BOOL bBold) | 项 | 设置项目的粗体状态 |
COLORREF SetItemTextBkColor(HTREEITEM hItem, COLORREF rgb) | 项 | 设置项目文本的背景颜色 |
COLORREF SetItemTextColor(HTREEITEM hItem, COLORREF rgb) | 项 | 设置项目的文本颜色 |
CXHtmlTree& SetLogfont(LOGFONT * pLogFont) | 树形控件 | 为树设置新的 LOGFONT |
COLORREF SetTextColor(COLORREF rgb) | 树形控件 | 设置树的文本颜色 |
CXHtmlTree& SetUseLogfont(BOOL bFlag) | 树形控件 | 设置标志以指示是否应使用 LOGFONT 结构(TRUE = 使用 LOGFONT) |
复选框
您可以独立于启用智能复选框(使用 SetSmartCheckBox()
)启用树的复选框(使用 SetHasCheckBoxes()
)。当复选框启用时,将为各种复选框状态创建内部状态图像列表。此创建是在 CreateCheckboxImageList()
中执行的(参见 CreateCheckboxImageList.cpp)。对于每种可能的状态,都会(使用 David Zhao 优秀的 CVisualStylesXP 类)为冷状态和热状态创建位图。显然,这意味着模态处理,但由于我可以使用 CTreeCtrl::SetItemState()
,因此跟踪项目状态并不太复杂。此外,我设计了图像列表,使常见的状态转换变得简单。在下表中,您可以看到从“冷”状态到“热”状态涉及与 8 进行 OR 运算,从“正常”状态到“禁用”状态涉及与 4 进行 OR 运算。
XHtmlTree 复选框状态 | ||||
---|---|---|---|---|
冷 | 热 | |||
正常 | 禁用 | 正常 | 禁用 | |
未选中 | 0001 | 0101 | 1001 | 1101 |
Checked | 0010 | 0110 | 1010 | 1110 |
三态 | 0011 | 0111 | 1011 | 1111 |
以下是为支持 XHtmlTree 复选框而实现的函数
函数 | 描述 |
---|---|
void CheckAll(BOOL bCheck) | 将所有项目的复选框设置为 bCheck 状态 |
BOOL GetCheck(HTREEITEM hItem) | 如果项目被选中,则返回 TRUE。如果项目未被选中或处于三态,则返回 FALSE。 |
int GetCheckedCount() | 返回树中已选中项目的总数 |
int GetChildrenCheckedCount(HTREEITEM hItem) | 返回子项的选中数量 |
HTREEITEM GetFirstCheckedItem() | 返回第一个选中的项目,如果没有则返回 NULL |
BOOL GetHasCheckBoxes() | 如果树有复选框,则返回 TRUE |
HTREEITEM GetNextCheckedItem(HTREEITEM hItem) | 返回下一个被选中的项目,如果没有则返回 NULL |
HTREEITEM GetPrevCheckedItem(HTREEITEM hItem) | 返回上一个选中的项目,如果没有则返回 NULL |
BOOL GetSelectFollowsCheck() | 如果选中项目也会导致其被选中,则返回 TRUE |
BOOL GetSmartCheckBox() | 如果智能复选框已启用,则返回 TRUE |
BOOL IsChecked(HTREEITEM hItem) | 如果项目被选中,则返回 TRUE。如果项目未被选中或处于三态,则返回 FALSE。 |
CXHtmlTree& SetCheck(HTREEITEM hItem, BOOL fCheck = TRUE) | 将项目选中状态设置为 fCheck |
CXHtmlTree& SetCheckChildren(HTREEITEM hItem, BOOL fCheck) | 将子项的选中状态设置为 fCheck |
CXHtmlTree& SetHasCheckBoxes(BOOL bHasCheckBoxes) | 如果 bHasCheckBoxes 为 TRUE,则为树启用复选框 |
CXHtmlTree& SetSelectFollowsCheck(BOOL bFlag) | 如果 bFlag 为 TRUE,选中一个项目也会导致它被选中 |
CXHtmlTree& SetSmartCheckBox(BOOL bFlag) | 如果 bFlag 为 TRUE,则启用智能复选框 |
键盘快捷键
XHtmlTree 支持标准 Windows 键盘导航技术
键 | 描述 |
---|---|
向下和向上箭头键 | 将选择移动到下一/上一项;不展开 |
右箭头键 | 展开当前选定的项(如果它已折叠),选择第一个子项 |
左箭头键 | 折叠当前选定的项(如果它已展开),选择父项 |
Page Down | 将选择移动到树窗口中的最后一项;根据需要翻页 |
Page Up | 将选择移动到树窗口中的第一项;根据需要翻页 |
Ctrl+Page Down | 滚动到树窗口中的最后一项;根据需要翻页;选择不改变 |
Ctrl+Page Up | 滚动到树窗口中的第一项;根据需要翻页;选择不改变 |
退格键 | 将选择移动到父项 |
End | 将选择移动到最后一项;不展开 |
Home | 将选择移动到第一项;不展开 |
Ctrl+End | 滚动到末尾;选择不变,不展开 |
Ctrl+Home | 滚动到开头;选择不变,不展开 |
数字键盘上的星号(*) | 展开选中项下的所有项 |
数字键盘上的加号 (+) | 展开选中的项目 |
数字键盘上的减号 (-) | 折叠选中的项目 |
树形导航和管理
以下是为支持 XHtmlTree 导航而实现的函数
函数 | 描述 |
---|---|
HTREEITEM GetLastItem(HTREEITEM hItem) | 检索树中的最后一项 |
HTREEITEM GetNextCheckedItem(HTREEITEM hItem) | 检索下一个已勾选的项 |
HTREEITEM GetNextItem(HTREEITEM hItem) | 检索树中的下一项。这会像树完全展开时视觉上显示的那样,从上到下遍历树。 |
HTREEITEM GetNextItem(HTREEITEM hItem, UINT nCode) | 检索与 hItem 具有指定关系(由 nCode 参数指示)的项目 |
HTREEITEM GetPrevCheckedItem(HTREEITEM hItem) | 检索上一个已勾选的项 |
HTREEITEM GetPrevItem(HTREEITEM hItem) | 检索树中的上一项。这会像树完全展开时视觉上显示的那样,从上到下遍历树。 |
初始化树
用一条语句初始化 XHtmlTree 很简单
m_Tree.Initialize(m_bCheckBoxes, TRUE) .SetSmartCheckBox(m_bSmartCheckBoxes) .SetHtml(m_bHtml) .SetStripHtml(m_bStripHtml) .SetImages(m_bImages);
工具提示
XHtmlTree 通过 CToolTipCtrl 支持标准工具提示,也支持 HTML 工具提示,这些工具提示由 Eugene Pustovoyt 优秀的 CPPToolTip 类显示。以下是 HTML 工具提示如何使用的示例
以下是此工具提示使用的 HTML
<br><hr color=lightsteelblue><br>
<table>
<tr>
<td><bmp idres=133 cx=110 cy=92 mask></td>
<td> </td>
<td width=180>金毛寻回犬是一种受欢迎的犬种,最初是为了在狩猎中捡回猎物而培育的。由于其天性友善且易于训练,因此它是最常见的家庭犬之一。</td>
</tr>
</table>
这都是标准 HTML,除了 <bmp idres=133 cx=110 cy=92 mask>,它指定要从资源 ID 133 读取位图。
好的,那么 HTML 是从哪里来的呢,因为它显然不是项目文本?XHtmlTree 提供了一个新的 SetItemNote()
函数,它将可选的注释文本附加到项目。注释文本(如果存在)将代替项目文本用于工具提示。对于标准工具提示和 HTML 工具提示都是如此。但是,请记住,标准工具提示有 80 个字符的硬限制。
#define XHTMLTOOLTIPS
如果您包含 HTML 工具提示,则必须在项目中包含额外的文件 - 详情请参阅下面的“如何使用”部分。
关于工具提示的最后一点:您可以选择在工具提示即将显示时动态更改它。一条通知消息(WM_XHTMLTREE_DISPLAY_TOOLTIP
- 参见下面的“通知消息”)让您有机会在工具提示显示前使用 SetItemNote()
。举个例子,在 XHtmlTreeTestDlg.cpp 中,您将看到以下代码(此处已精简)
LRESULT CXHtmlTreeTestDlg::OnDisplayTreeToolTip(WPARAM wParam, LPARAM)
{
XHTMLTREEMSGDATA *pData = (XHTMLTREEMSGDATA *)wParam;
HTREEITEM hItem = pData->hItem;
CString strText = m_Tree.GetItemText(hItem);
// check if this is 'Galgo Español (Spanish Greyhound)'
if (_tcsncmp(strText, _T("Galgo"), 5) == 0)
{
// set new note for this item --
// zero tip width will use default width
m_Tree.SetItemNote(hItem,
_T("This is alternate text. ")
_T("For standard tooltip, it is limited to 80 characters."),
0);
}
return 0; // return 0 to allow tooltip to be displayed,
// 1 to prevent display
}
在演示应用程序中,您将看到
通知消息
对于所有通知消息,wParam
参数是指向 XHTMLTREEMSGDATA
结构的指针
struct XHTMLTREEMSGDATA { HWND hCtrl; // hwnd of XHtmlTree UINT nCtrlId; // id of XHtmlTree HTREEITEM hItem; // current item };
lParam
参数取决于具体消息。以下消息发送给 XHtmlTree 父级
Message | 描述 | lParam |
WM_XHTMLTREE_CHECKBOX_CLICKED | 点击复选框时发送 | 新的复选框状态(TRUE = 选中) |
WM_XHTMLTREE_DISPLAY_TOOLTIP | 当工具提示即将显示时发送 | 指向工具提示控件的指针(CToolTipCtrl 或 CPPToolTip ) |
WM_XHTMLTREE_INIT_TOOLTIP | 当工具提示控件正在初始化时发送 | 指向工具提示控件的指针(CToolTipCtrl 或 CPPToolTip ) |
WM_XHTMLTREE_ITEM_EXPANDED | 当项目被展开或折叠时发送 | 新项目状态(TRUE = 已展开) |
拖放
从版本 1.4 开始,XHtmlTree 支持拖放。以下拖放功能和操作已实现
- 有一个新的编译时符号来启用拖放代码的包含
#define XHTMLDRAGDROP
定义(或不定义)此符号也会正确设置TVS_DISABLEDRAGDROP
样式。 - 拖放是使用
CTreeCtrl::SetInsertMark()
API 实现的。例如,Firefox 书签就是使用这种方式。当一个项目被拖动时,您会看到一条实心细条——称为插入标记——显示在树中的项目之间。插入标记表示如果项目被放置,它将插入到树中的位置。 - 根据设计,传统的 OLE 样式拖动图像动画尚未实现,目前也没有计划这样做。
- 除了显示插入标记之外,您还可以选择通过
SetDropCursors()
函数显示三个自定义光标:禁止放置光标、放置移动光标和放置复制光标。演示应用程序包含每个示例光标 演示图片 描述 禁止放置 用于指示禁止放置区域;可以是树形控件外部的区域,或者是不允许作为放置目标的项。 放置移动 用于指示在释放鼠标左键时,拖动的项目将被移动。 放置复制 用于指示在释放鼠标左键时,拖动的项目将被复制。 - 放置复制与放置移动 - 有几种方法可以控制拖动的项目是复制还是移动
用户可以在拖动之前或拖动期间使用 Ctrl 键在复制和移动之间切换。 应用程序可以通过设置/重置 XHTMLTREE_DO_CTRL_KEY
拖动操作标志来控制是否识别 Ctrl 键。应用程序可以通过设置/重置 XHTMLTREE_DO_COPY_DRAG
拖动操作标志来更改 Ctrl 键的默认行为。 - 应用程序可以通过处理以下通知消息来控制拖动的每个阶段
WM_XHTMLTREE_BEGIN_DRAG
- 此消息在拖动开始时发送,包括被拖动的项目和XHTMLTREE_DO_COPY_DRAG
标志位的状态。请注意,在演示应用程序中,尝试拖动“灵缇犬组”中的“长犬”将被拒绝(参见演示日志)。WM_XHTMLTREE_END_DRAG
- 此消息在拖动终止时发送,无论是通过放置还是其他用户操作(例如按 ESC 键,右键单击鼠标,将项目放回自身,或放置到树形控件外部)。如果拖动因放置到有效的树形项(自身除外)而终止,此消息将包含建议的放置目标。如果拖动因任何其他原因终止,则将值 0 作为lParam
参数发送。请注意,在演示应用程序中,放置到“灵缇犬组”中的“长犬”将被拒绝(参见演示日志)。WM_XHTMLTREE_DROP_HOVER
- 当光标悬停在树形项目上时发送此消息,并包含可能成为放置目标的树形项目。请注意,在演示应用程序中,悬停在“灵缇犬组”中的“长犬”上将显示“禁止放置”光标。对于所有上述消息,一个指向
XHTMLTREEDRAGMSGDATA
结构的指针作为lParam
参数发送(在WM_XHTMLTREE_END_DRAG
消息的情况下可能为 NULL)。struct XHTMLTREEDRAGMSGDATA { HTREEITEM hItem; // item being dragged HTREEITEM hNewParent; // proposed new parent HTREEITEM hAfter; // drop target - item being dragged will // either sequentially follow this item, // or hAfter specifies the relationship // (TVI_FIRST, TVI_LAST, etc.) the // dragged item will have with hNewParent. // Note that TVI_xxxx constants are all // defined as 0xFFFFnnnn, with the 16 // high-order bits set. BOOL bCopyDrag; // TRUE = dropped item will be copied; // FALSE = dropped item will be moved };
应用程序可以通过
FALSE
(表示建议的操作可以继续)或TRUE
(表示不允许建议的操作)来响应这些消息。当响应WM_XHTMLTREE_BEGIN_DRAG
和WM_XHTMLTREE_END_DRAG
消息时,返回代码TRUE
将终止拖动。当响应WM_XHTMLTREE_DROP_HOVER
消息时,返回代码TRUE
将导致显示禁止放置光标。由于在没有消息处理程序的情况下,默认返回代码为 0 或
FALSE
,因此无需实现任何这些消息的处理程序即可启用拖放功能。 - 默认情况下,在拖动过程中,当光标接近控件顶部或底部时,树将自动滚动。树以三种不同的速度滚动,具体取决于光标与边缘的距离。此外,应用程序可以选择两种整体速度设置之一 - 正常或快速 - 并且还可以完全禁用拖动滚动。拖动滚动由拖动操作标志
XHTMLTREE_DO_SCROLL_NORMAL
和XHTMLTREE_DO_SCROLL_FAST
控制。如果这两个标志位都为 0,则不会发生滚动。 - 默认情况下,在拖动过程中,当光标悬停在节点上时,树将自动展开该节点。此行为可以通过拖动操作标志位
XHTMLTREE_DO_AUTO_EXPAND
禁用。 - 通过结合使用
SetInsertMark()
API 和自动展开,用户可以在任何现有节点之后放置项目(或分支)。然而,这两个机制不允许“放置到下面”,即放置导致子项的创建。为了适应这一点,用户可以在拖动之前或拖动期间使用 Shift 键。按住 Shift 键会使放置变为“放置到下面”:插入标记被移除,取而代之的是放置目标(建议的新父项)被高亮显示。此行为可以通过拖动操作标志位XHTMLTREE_DO_SHIFT_KEY
禁用。 - 涉及禁用或只读项目的拖动操作不会被 XHtmlTree 明确禁止。如果您想阻止拖动禁用或只读项目,您应该为
WM_XHTMLTREE_BEGIN_DRAG
消息设置处理程序。请参阅 XHtmlTreeTestDlg.cpp 获取示例。 - 存在一个已知问题:当按住 Ctrl 键时,ESC 键无法终止拖动。
分隔符 |
![]() |
要亲自尝试分隔符,您可以使用演示应用程序中的右键菜单。
以下分隔符功能和操作已实现
- 函数
InsertSeparator()
在指定项目之后插入一个分隔符。分隔符的数量没有限制。 - 函数
IsSeparator()
允许您测试树形项目是否为分隔符。 - 您可以使用
SetItemTextColor()
更改单个分隔符的颜色,或者可以使用SetSeparatorColor()
更改所有分隔符的颜色。默认分隔符颜色是GetSysColor(COLOR_GRAYTEXT)
返回的颜色。 - 分隔符可以像任何其他树形项目一样被选中。
- 分隔符可以像任何其他树形项目一样被拖动。
- 分隔符不能有文本。
- 分隔符不能有子项。尝试将项目放置在分隔符上将始终导致项目插入到分隔符之后(不允许“放置到下方”)。但是,允许将分隔符放置在非分隔符项目下方。
- 分隔符不能通过
TVN_BEGINLABELEDIT
编辑。 - 分隔符包含在子项计数中,但对智能复选框没有影响。
- 您可以使用属性 separator=1 指定从 XML 文件加载分隔符。
如何使用
要将 XHtmlTree 集成到您自己的应用程序中,您首先需要将以下文件添加到您的项目
- CreateCheckboxImageList.cpp
- CreateCheckboxImageList.h
- VisualStylesXP.cpp
- VisualStylesXP.h
- XHtmlDraw.cpp
†
- XHtmlDraw.h
- XHtmlDrawLink.cpp
†
- XHtmlDrawLink.h
- XHtmlTree.cpp
- XHtmlTree.h
- XNamedColors.cpp
†
- XNamedColors.h
- XString.cpp
†
- XString.h
标有 †
的文件必须在 Visual Studio 中设置为不使用预编译头文件。
如果您想使用 HTML 工具提示,那么您还必须包含以下文件
- CeXDib.cpp
- CeXDib.h
- PPDrawManager.cpp
- PPDrawManager.h
- PPHtmlDrawer.cpp
- PPHtmlDrawer.h
- PPTooltip.cpp
- PPTooltip.h
最后,如果您想包含 XML 函数,则必须包含这两个文件
- XmlDocument.cpp
- XmlDocument.h
然后声明 CTreeCtrl
对象的变量,并将其类型更改为 CXHtmlTree
CXHtmlTree m_Tree;
现在您就可以在您的项目中使用 CXHtmlTree
了。
XHtmlTree 编译时选项
有三个编译时选项控制 XHtmlTree 包含哪些功能。这些选项可以通过编辑 XHtmlTree.h、将其作为 #define
语句包含(例如,在 stdafx.h 中),或者通过 IDE 定义它们(在 VS2005 中,转到项目 | 属性 | 配置属性 | C/C++ | 预处理器 | 预处理器定义;确保对所有配置都执行此操作)。
XHTMLHTML
- 定义后,此选项将启用在树形项中使用 HTML。XHTMLTOOLTIPS
- 定义后,此选项将启用 HTML 工具提示的使用。XHTMLXML
- 定义后,此选项将启用 XML 数据的加载/保存。XHTMLDRAGDROP
- 定义后,此选项将启用拖放功能。
下表显示了每个编译时选项需要包含的源模块(包括未选择任何选项的情况,这在 MinDialog 演示中使用了)
XHtmlTree 编译时选项 | ||||
---|---|---|---|---|
源模块 | 无 | XHTMLHTML | XHTMLTOOLTIPS | XHTMLXML |
CeXDib.cpp |
|
|
|
|
CeXDib.h |
|
|
|
|
CreateCheckboxImageList.cpp |
|
|
|
|
CreateCheckboxImageList.h |
|
|
|
|
PPDrawManager.cpp |
|
|
|
|
PPDrawManager.h |
|
|
|
|
PPHtmlDrawer.cpp |
|
|
|
|
PPHtmlDrawer.h |
|
|
|
|
PPTooltip.cpp |
|
|
|
|
PPTooltip.h |
|
|
|
|
VisualStylesXP.cpp |
|
|
|
|
VisualStylesXP.h |
|
|
|
|
XHtmlDraw.cpp † |
|
|
|
|
XHtmlDraw.h |
|
|
|
|
XHtmlDrawLink.cpp † |
|
|
|
|
XHtmlDrawLink.h |
|
|
|
|
XHtmlTree.cpp |
|
|
|
|
XHtmlTree.h |
|
|
|
|
XmlDocument.cpp |
|
|
|
|
XmlDocument.h |
|
|
|
|
XNamedColors.cpp † |
|
|
|
|
XNamedColors.h |
|
|
|
|
XString.cpp † |
|
|
|
|
XString.h |
|
|
|
|
†
的文件必须在 Visual Studio 中设置为不使用预编译头文件。拖放(XHTMLDRAGDROP
)所需的文件与“无”下列出的文件相同。
使用 XML
您可以按照您当前的方式加载树,或者(如果您在 XHtmlTree.h 中定义了 XHTMLXML )您可以使用 LoadXmlFromXXXX 函数 - 请参阅 XHtmlTreeTestDlg.cpp 获取示例。XHtmlTree 使用的 XML 解析器极其简单,不执行任何严格的错误检查。在 dogs.xml 中此精简的 XML 片段中,请注意 HTML 标签必须用字符实体进行转义 |
![]() |
- name - 这是将插入到树中的项目文本。它可以包含 HTML 格式。
- checked - 为项目指定初始选中状态(如果为“1”)或未选中状态(“0”)。默认为未选中。
- enabled - 为项目指定初始启用状态(如果为“1”)或未启用状态(“0”)。默认为启用。
- separator - 指定项目是分隔符(如果为“1”)或不是分隔符(“0”)。默认为不是分隔符。
- image - 将图像列表中的图像与项目关联。使用
SetImageList()
设置图像列表。 - text-color - 项目的文本颜色;覆盖全局树文本颜色。
- text-background-color - 项目的文本背景颜色;覆盖全局树文本背景颜色。
- note-width - 此项目的工具提示宽度。默认值为 0 表示将使用启发式方法确定适当的宽度。
- note - 此文本将代替标准工具提示文本显示。如果已定义
XHTMLTOOLTIPS
(参见 XHtmlTree.h),则此文本可以包含 HTML 标签。
您可以从资源、文件或内存缓冲区加载 XML,也可以将 XML 保存到文件。
以下是为支持 XML 而实现的函数
函数 | 描述 |
---|---|
BOOL ConvertBuffer(const BYTE * inbuf, DWORD inlen, BYTE ** outbuf, DWORD& outlen, ConvertAction eConvertAction = NoConvertAction) | 将 XML 缓冲区转换为 Unicode/从 Unicode 转换 |
CString GetXmlText(HTREEITEM hItem, LPCTSTR lpszElem) | 检索项目的 XML |
BOOL LoadXmlFromBuffer(const BYTE * pBuf, DWORD len, ConvertAction eConvertAction) | 从内存缓冲区加载 XML |
BOOL LoadXmlFromFile(LPCTSTR lpszFile, ConvertAction eConvertAction) | 从文件加载 XML |
BOOL LoadXmlFromResource(HINSTANCE hInstance, LPCTSTR lpszResId, LPCTSTR lpszResType, ConvertAction eConvertAction) | 从资源加载 XML |
BOOL SaveXml(HTREEITEM hItem, LPCTSTR lpszFileName, BOOL bSaveAsUTF16) | 将 XML 保存到文件 |
参考文献
以下是我在这篇文章中提到的链接。我还包含了我在 CodeProject 上的文章链接,我在演示应用程序中使用了它们。
- MSDN 上的树形控件拖放操作
- 使用自定义绘制自定义控件外观,来自 MSDN
- Zafir Anjum 的树形控件文章
- CTreeComboBox: 支持 XML 的多行树形组合框 作者:John Melas。本文包含我在 XHtmlTree 中使用的
CXmlDocument
类。 - 为 OWNERDRAW 控件添加 XP 视觉样式支持 作者:David Y. Zhao。我用它来创建复选框位图。
- CPPToolTip 作者 Eugene Pustovoyt。我使用这个类来实现 HTML 工具提示。
- XBreadCrumbBar - 使用超链接和 HTML 绘制面包屑导航
- XColourPicker - 又一个颜色选择器控件
- XEditPrompt - 带有类似网页提示的 CEdit 派生控件
- XGlyphButton - 一个简单的图像按钮控件
- XHtmlDraw - 使用 HTML 标签和锚链接绘制文本 - 我用它来绘制包含 HTML 格式的树形项目。
- XHyperLink - 又一个超链接控件
- XListBox - 具有可选文本和背景颜色的自绘 CListBox
- XResFile - 存储在资源中的文件:第 1 部分 - 文本和二进制
- XString - 非 MFC 非 STL 字符串函数
修订历史
版本 1.6 - 2007 年 12 月 19 日
版本 1.5 - 2007 年 11 月 7 日
- 修复了 XML 输入错误(如果没有图像列表则崩溃);由 Berni Slootbeek 报告。
- 更新至 XHtmlDraw v1.2。
版本 1.4 - 2007 年 11 月 4 日
- 添加了对 拖放 的支持,由 David McMinn 建议。感谢您的帮助,David!
版本 1.3 - 2007 年 10 月 16 日
- 添加了“最小对话框”的演示项目。此项目展示了如何使用带智能复选框的 XHtmlTree,但没有 HTML、XML 或 HTML 工具提示。这使得可执行文件大小减少了约 130KB。
版本 1.2 - 2007 年 10 月 14 日
- 调整了显示性能。
- 演示应用程序的少量修改。
- 在演示应用程序中添加了
WM_CONTEXTMENU
的处理程序。 - 添加了
CXHtmlTree::EnableBranch(HTREEITEM hItem, BOOL bEnabled)
- 修复了使用空格键选中项目的问题,由 David McMinn 报告。
- 修复了就地编辑框不关闭的问题,由 David McMinn 报告。
- 使用 David McMinn 提供的代码修复了几个就地编辑问题。
版本 1.1 - 2007 年 10 月 10 日
- 添加了 MDI 应用程序的演示项目。
- 消除了桌面图标闪烁的问题,由 Greg Cadmes 报告。
- 修复了系统颜色定义版本问题,由 Graham Shanks 报告。
- 修复了
CVisualStylesXP::UseVisualStyles()
的编译问题,由 Graham Shanks 报告。 - 智能复选框现在默认为关闭 (FALSE);由 Graham Shanks 建议。
- 添加了对禁用树的颜色支持,由 Graham Shanks 建议。
- 修复了
CheckAll()
处理多个根节点的问题,由 Rolando E. Cruz-Marshall 报告。 - 修复了
SetCheck()
的问题,由 Graham Shanks 报告。 - 添加了
Get/SetReadOnly()
函数,由 Graham Shanks 建议。SetReadOnly()
函数可在活动(读/写)和非活动(只读)之间切换所有复选框,并允许/阻止就地编辑。设置为只读时,没有自动的视觉指示表明树是只读的。您可以使用SetBkColor()
函数设置只读树的背景,以指示只读状态。还在演示应用程序中添加了设置只读状态的选项。 - 将西施犬添加到狗列表中,由 bolivar123 建议。
版本 1.0 - 2007 年 8 月 9 日
- 首次公开发布
用法
本软件发布到公共领域。您可以以任何您喜欢的方式使用它,但不得出售此源代码。如果您修改或扩展它,请考虑在此处发布新代码供大家分享。本软件“按原样”提供,不提供任何明示或暗示的保证。对于本软件可能造成的任何损害或业务损失,我不承担任何责任。