首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ Builder 建立帶核取方塊的 TreeView

     編輯:關於C++

啟用 TVS_CHECKBOXES 樣式並處理父子節點聯動勾選

透過 SetWindowLong 加入 TVS_CHECKBOXES 樣式,TreeView 即顯示核取方塊。再封裝取得/設定節點勾選狀態函數,於滑鼠事件中實現點選父節點連帶勾選所有子孫節點。

啟用核取方塊 (FormCreate)

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    SetWindowLong(TreeView1->Handle, GWL_STYLE,
        GetWindowLong(TreeView1->Handle, GWL_STYLE) | TVS_CHECKBOXES);
}

核心輔助函數

// 取得節點勾選狀態
bool GetNodeChecked(TTreeNode *ANode)
{
    TVITEM tvItem;
    tvItem.mask = TVIF_HANDLE | TVIF_STATE;
    tvItem.hItem = ANode->ItemId;
    tvItem.stateMask = TVIS_STATEIMAGEMASK;
    TreeView_GetItem(ANode->TreeView->Handle, &tvItem);
    return ((BOOL)(tvItem.state >> 12) - 1); // 狀態映像索引 1=未勾選, 2=勾選
}

// 設定節點勾選狀態
void SetNodeChecked(TTreeNode *ANode, bool IsSetToChecked)
{
    TVITEM tvItem;
    tvItem.mask = TVIF_HANDLE | TVIF_STATE;
    tvItem.hItem = ANode->ItemId;
    tvItem.stateMask = TVIS_STATEIMAGEMASK;
    tvItem.state = INDEXTOSTATEIMAGEMASK(IsSetToChecked ? 2 : 1);
    TreeView_SetItem(ANode->TreeView->Handle, &tvItem);
}

// 遞歸設定子孫節點
void SetChildChecked(TTreeNode *ANode, bool yn)
{
    SetNodeChecked(ANode, yn);
    for (int i = 0; i < ANode->Count; i++)
        SetChildChecked(ANode->Item[i], yn);
}

滑鼠事件處理聯動勾選

TTreeNode *ClickNode; // 滑鼠移動時暫存節點
bool NodeChecked;     // 暫存該節點原本勾選狀態

void __fastcall TForm1::TreeView1MouseMove(TObject *Sender,
    TShiftState Shift, int X, int Y)
{
    ClickNode = TreeView1->GetNodeAt(X, Y);
    if (ClickNode != NULL)
        NodeChecked = GetNodeChecked(ClickNode); // 記錄點擊前狀態
}

void __fastcall TForm1::TreeView1MouseDown(TObject *Sender,
    TMouseButton Button, TShiftState Shift, int X, int Y)
{
    if (ClickNode != NULL) {
        // 若狀態改變 (使用者點擊核取方塊),同步子孫節點
        if (GetNodeChecked(ClickNode) != NodeChecked) {
            NodeChecked = !NodeChecked;
            SetChildChecked(ClickNode, NodeChecked);
        }
    }
}

原理說明

  • TVIS_STATEIMAGEMASK 狀態位元第 12-15 位存放狀態映像索引 (1-based)。
  • INDEXTOSTATEIMAGEMASK(1) = 未勾選,(2) = 勾選。
  • 於 MouseMove 記錄點擊前狀態,MouseDown 比較點擊後狀態,若不同表示使用者點擊了核取方塊,遞歸設定所有子孫節點相同狀態。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved