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

CQuadStateTree

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (16投票s)

2014年11月28日

CPOL

6分钟阅读

viewsIcon

40710

downloadIcon

1769

派生自 CTreeCtrl 的控件,具有四种复选框状态

Quad State Tree Control

引言

我需要一个具有标准CTreeCtrl所不具备的多个功能的树形控件。

  1. 具有不确定状态的复选框。当树形控件的子项不全处于相同状态时,该项的复选框应显示不确定状态。
  2. 将父树项的复选框状态设置为选中或取消选中,应自动将所有其子树项的状态设置为相同状态。
  3. 将子树项的复选框状态设置为选中或取消选中,应自动将其父树项的状态设置为相应状态。
  4. 并非树形控件中的所有项都需要复选框。有时,树的根节点仅需作为标签占位符。
  5. 通知。如果树形控件的父窗口在树项复选框状态更改时收到详细的通知消息,那将是非常好的。
  6. 能够阻止复选框状态的更改。当父窗口收到通知(见上文)时,应有可能阻止复选框状态的更改。

本文档介绍的CQuadStateTree类实现了所有这些需求,再加上一些额外的功能。

背景

您可能会问,为什么是 Quad State(四态)?这是因为树形控件中的每个复选框可以有四种状态。当然,有基本的选中和未选中,以及熟悉的“不确定”状态。但我增加了一种第四种状态,即“none”(无)。您可能会说“none”不是一种状态,但实际上是。当树形控件中的其他项都有复选框时,如何指定某一个树项不应有复选框?

当然,为了使“none”状态有意义,必须对其施加基本限制。限制是:为了使树项具有“none”状态,其所有父项(沿树向上直到根节点)也必须处于“none”状态。无法选择父项但无法选择子项是没有意义的。

Using the Code

在您自己的项目中开始使用此代码的第一步是将QuadStateTree.hQuadStateTree.cpp文件添加到您的项目中。然后,在任何需要访问CQuadStateTree类的文件中,只需#include QuadStateTree.h

由于CQuadStateTree是从CTreeCtrl派生的,因此您可以使用此类的使用方式与使用CTreeCtrl完全相同,但存在以下API例外:

CQuadStateTree 数据类型

CQuadStateTree使用以下自定义数据类型。

TVCS_CHECKSTATE

TVCS_CHECKSTATE enum 定义了四种可能的复选框状态。

语法

enum TVCS_CHECKSTATE
{
    TVCS_NONE          = -1,
    TVCS_UNCHECKED     =  0,
    TVCS_CHECKED       =  1,
    TVCS_INDETERMINATE =  2 
};

成员

TVCS_NONE 该树项没有与之关联的复选框。
TVCS_UNCHECKED 该树项的复选框中没有勾选标记。
TVCS_CHECKED 该树项的复选框中有一个勾选标记。
TVCS_INDETERMINATE 该树项有子项,并且子项是选中和未选中状态的混合。

NMTVNCHECK

NMTVNCHECK 结构包含有关树项复选框状态更改的信息。

语法

typedef struct tagTVNCHECK    
{
    NMHDR hdr;                     
    HTREEITEM hTreeItem;           
    LPARAM lParam;                 
    TVCS_CHECKSTATE OldCheckState; 
    TVCS_CHECKSTATE NewCheckState; 
    HTREEITEM TriggerItem;         
} NMTVNCHECK, *LPNMTVNCHECK;

成员

hdr NMHDR 结构,包含有关 TVN_CHECK 通知消息的信息。
hTreeItem 要从中检索复选框状态的树项的句柄。
lParam hTreeItem关联的应用程序特定数据。
OldCheckState hTreeItem的旧复选框状态。
NewCheckState hTreeItem的新复选框状态。
TriggerItem 由用户切换或在调用SetCheck()时指定的树项的句柄。

CQuadStateTree 通知消息

TVN_CHECK 通知代码

TVN_CHECK 通知作为 WM_NOTIFY 消息发送到父窗口,以通知父窗口复选框即将更改状态。

语法

TVN_CHECK

    pNMTvnCheck = (LPNMTVNCHECK) lParam

参数

pNMTvnCheck 指向 NMTVNCHECK 结构的指针。

返回值

如果NMTVNCHECK结构中的hTreeItemTriggerItem成员指向同一树项,则返回非零值将阻止树项复选框更改状态。

在所有其他情况下,将忽略返回值。


ON_TVN_CHECK 消息映射宏

使用ON_TVN_CHECK宏来定义TVN_CHECK通知处理函数。

语法

ON_TVN_CHECK(<nID>, <pFunction>)

参数

nID 树形控件的标识号
pFunction 当发送TVN_CHECK通知时要调用的成员函数的指针。

备注

pFunction必须使用以下原型声明:

afx_msg void memberFxn( NMHDR * pNMHDR, LRESULT * pResult );

其中斜体参数是:

pNMHDR
指向NMHDR结构的指针,可以将其强制转换为 LPNMTVNCHECK 结构指针。

pResult
指向您在返回前设置的结果代码的指针。


CQuadStateTree 成员函数

CQuadStateTree::CQuadStateTree

用于构造CQuadStateTree对象的类构造函数。

语法

CQuadStateTree();

CQuadStateTree::~CQuadStateTree

删除CQuadStateTree对象时调用的类析构函数。

语法

virtual ~CQuadStateTree();

CQuadStateTree::GetCheck

语法

TVCS_CHECKSTATE GetCheck(
    HTREEITEM hTreeItem) const;

参数

hTreeItem 要从中检索复选框状态的树项的句柄。

返回值

返回一个 TVCS_CHECKSTATE enum,指示复选框的当前状态。

备注

此函数与 CTreeCtrl::GetCheck 相同。唯一区别在于返回值是作为 TVCS_CHECKSTATE enum 返回,而不是BOOL


CQuadStateTree::SetCheck

语法

BOOL SetCheck (
    HTREEITEM hTreeItem,
    TVCS_CHECKSTATE NewCheckState = TVCS_CHECKED);

参数

hTreeItem 要接收复选框状态更改的树项的句柄。
NewCheckState 新的复选框状态。默认情况下,复选框状态设置为TVCS_CHECKED

返回值

成功则返回非零值;否则返回零。

备注

SetCheck()因以下原因返回零:

  1. NewCheckStateTVCS_INDETERMINATETVCS_INDETERMINATE状态仅在树项的子项状态不同时由控件设置。无法通过SetCheck()设置TVCS_INDETERMINATE
  2. NewCheckStateTVCS_NONE。将复选框设置为TVCS_NONE状态的唯一方法是,hTreeItem的所有父树项都已设置为TVCS_NONE。要设置TVCS_NONE状态,您必须从树的根节点开始,向下进行。

CQuadStateTree::Create

调用此函数以创建控件(子窗口)并将其与CQuadStateTree对象关联。

语法

virtual BOOL Create(
    DWORD dwStyle,
    const RECT& rect,
    CWnd* pParentWnd,
    UINT nID);

参数

dwStyle 指定树视图控件的样式。应用窗口样式,如 CreateWindow 中所述,以及平台 SDK中所述的任何 树视图控件样式的组合。
rect RECT结构的引用,该结构描述了要创建的窗口的大小和位置,以pParentWnd的客户区坐标表示。
pParentWnd 指向作为控件父窗口的窗口的指针。
nID 控件的子窗口 ID。

CQuadStateTree::CreateEx

调用此函数以创建控件(子窗口)并将其与CQuadStateTree对象关联。

语法

virtual BOOL CreateEx(
    DWORD dwExStyle,
    DWORD dwStyle,
    const RECT& rect,
    CWnd* pParentWnd,
    UINT nID);

参数

dwExStyle 指定要创建控件的扩展样式。有关 扩展 Windows 样式的列表,请参阅平台 SDK中 CreateWindowExdwExStyle参数。
dwStyle 指定树视图控件的样式。应用窗口样式,如 CreateWindow 中所述,以及平台 SDK中所述的任何 树视图控件样式的组合。
rect RECT结构的引用,该结构描述了要创建的窗口的大小和位置,以pParentWnd的客户区坐标表示。
pParentWnd 指向作为控件父窗口的窗口的指针。
nID 控件的子窗口 ID。

备注

我尚未探索 树视图扩展样式,因此我不知道它们将如何影响此控件。


从CQuadStateTree派生

CQuadStateTree必须处理多个不同的消息才能正常工作。如果您从CQuadStateTree派生自己的控件,并且在派生类中处理相同的消息,请务必从您的消息处理函数调用CQuadStateTree消息处理函数。

此处列出了CQuadStateTree处理的消息以及处理它们的函数的名称:

NM_CLICK CQuadStateTree::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
NM_TVSTATEIMAGECHANGING CQuadStateTree::OnNMTvStateImageChanging(NMHDR *pNMHDR, LRESULT *pResult)
TVN_KEYDOWN CQuadStateTree::OnTvnKeydown(NMHDR *pNMHDR, LRESULT *pResult)
TVN_ITEMCHANGED CQuadStateTree::OnTvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
TVM_SETITEM CQuadStateTree::OnTvmSetitem(WPARAM wp, LPARAM lp)

历史

  • 2014年11月28日 - 首次发布
© . All rights reserved.