Builder C ++:带有复选框项的TTreeView

时间:2015-04-17 14:50:41

标签: checkbox treeview c++builder c++builder-xe5

我需要创建一个带有复选框节点的树视图,如下图所示:

enter image description here

怎么做?

THX!

1 个答案:

答案 0 :(得分:1)

TTreeView组件本身不支持复选框,但标准Windows TREEVIEW控件通过TVS_CHECKBOXES style支持:

  

TVS_CHECKBOXES

     

Version 4.70。为树视图控件中的项启用复选框。仅当图像与项目关联时,才会显示复选框。当设置为此样式时,控件有效地使用DrawFrameControl来创建和设置包含两个图像的状态图像列表。状态图像1是未选中框,状态图像2是复选框。将状态图像设置为零将完全删除复选框。有关详细信息,请参阅Working with state image indexes

     

Version 5.80。即使没有图像与项目相关联,也会显示一个复选框。

     

使用此样式创建树视图控件后,无法删除样式。相反,您必须销毁控件并在其位置创建一个新控件。销毁树视图控件不会破坏复选框状态图像列表。你必须明确地销毁它。通过向树视图控件发送TVM_GETIMAGELIST消息来获取状态图像列表的句柄。然后使用ImageList_Destroy销毁图像列表。

     

如果要使用此样式,则必须在创建树视图控件之后以及填充树之前将TVS_CHECKBOXES样式设置为SetWindowLong。否则,复选框可能会取消选中,具体取决于时间问题。

要将TVS_CHECKBOXES样式应用于TTreeView组件,您应该派生一个新组件并覆盖虚拟CreateParams()方法,例如:

class TMyTreeView : public TTreeView
{
protected:
    virtual void __fastcall CreateParams(TCreateParams &Params);
};

void __fastcall TMyTreeView::CreateParams(TCreateParams &Params)
{
    TTreeView::CreateParams(Params);
    Params.Style |= TVS_CHECKBOXES;
}

要在代码中指定复选框状态,您可以使用TreeView_GetItem() / TreeView_SetItem()宏根据需要切换节点的状态图像索引。

或者,更灵活的方法是简单地将您自己的TImageList分配给TTreeView::StateImages属性,并将其填入您想要的任何复选框图像,然后您可以设置TTreeNode::StateIndex属性如所须。要对复选框上的用户输入做出反应,请使用TTreeView::OnClickTTreeView::OnKeyDown事件相应地切换TTreeNode::StateIndex

void __fastcall ToggleTreeNodeCheckBox(TTreeNode *Node)
{
    if ((Node) && (Node->StateIndex != -1))
    {
        if (Node->StateIndex == MyCheckedStateImageIndex)
            Node->StateIndex = MyUncheckedStateImageIndex;
        else
            Node->StateIndex = MyCheckedStateImageIndex;
    }
}

void __fastcall TMyForm::TreeView1Click(TObject *Sender)
{
    TPoint P;
    ::GetCursorPos(&P);
    // or: P = Mouse->CursorPos;
    // or: POINTS pts = MAKEPOINTS(::GetMessagePos()); P = Point(pts.x, pts.y);
    P = TreeView1->ScreenToClient(P);
    if (TreeView1->GetHitTestInfoAt(P.x, P.y).Contains(htOnStateIcon))
        ToggleTreeNodeCheckBox(TreeView1->GetNodeAt(P.x, P.y));
}

void __fastcall TMyForm1::TreeView1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
    if (Key == VK_SPACE)
        ToggleTreeNodeCheckBox(TreeView1->Selected);
}