1. 消息事件
(1)鼠標點擊當前ITEM的CHECKBOX:引發NM_CLICK事件并傳遞TVHT_ONITEMSTATEICON。
(2)鼠標點擊當前ITEM的TEXT:引發NM_CLICK事件。
(3)鼠標點擊新ITEM的CHECKBOX:引發TVN_SELCHANGED事件、NM_CLICK事件并傳遞TVHT_ONITEMSTATEICON。
(4)鼠標點擊新ITEM的TEXT:引發NM_CLICK事件、TVN_SELCHANGED事件。
2. 消息事件總結
點擊ITEM會引發NM_CLICK事件。若點擊CHECKBOX則傳遞TVHT_ONITEMSTATEICON。
因此可不處理TVN_SELCHANGED事件而只處理NM_CLICK事件。
3. 消息處理注意事項
(1)點擊CHECKBOX后會自動更新CheckBox的狀態,因此在處理代碼中不需要使用SetCheck函數設置狀態,而GetCheck函數返回也是其原始狀態。
(2)點擊新CHECKBOX后不會自動將對應的ITEM設置為選擇狀態,需要使用SelectItem函數進行設置。
4. 使用方法
(1)若傳遞TVHT_ONITEMSTATEICON
獲取選擇ITEM的狀態并取反
若有子項則所有子項設置為一致
若沒有子項則
若當前狀態為TRUE則設置父項為TRUE;否則遍歷所有兄弟項,若全為FALSE則設置父項為FALSE。
若選擇了新ITEM則設置新ITEM為選擇項
(2)若未傳遞TVHT_ONITEMSTATEICON
設置更新ITEM狀態,獲取選擇ITEM的狀態
若有子項則所有子項設置為一致
若沒有子項則
若當前狀態為TRUE則設置父項為TRUE;否則遍歷所有兄弟項,若全為FALSE則設置父項為FALSE。
5. 響應NM_CLICK事件的函數代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
void CTestTimerDlg::OnClickTree(NMHDR* pNMHDR, LRESULT * pResult) { // TODO: Add your control notification handler code here CPoint point; UINT uFlag; //接收有關點擊測試的信息的整數 HTREEITEM hTree; BOOL bCheck; GetCursorPos(&point); //獲取屏幕鼠標坐標 m_TreeCtrl.ScreenToClient(&point); //轉化成客戶坐標 hTree = m_TreeCtrl.HitTest(point,&uFlag); //返回與CtreeTtrl關聯的光標的當前位置和句柄 if ((TVHT_NOWHERE & uFlag)) { return ; } if (hTree && (TVHT_ONITEMSTATEICON & uFlag)) //點中復選框 { m_TreeCtrl.SelectItem(hTree); CString temp = m_TreeCtrl.GetItemText(hTree) + "\r\n" ; TRACE(temp); bCheck = m_TreeCtrl.GetCheck(hTree); //獲取當前復選狀態 SetChildCheck(hTree,!bCheck); //設置子項復選狀態 SetParentCheck(hTree, bCheck); //設置父項復選狀態 } *pResult = 0; } |
1
2
3
4
5
6
7
8
9
10
11
|
void CTestTimerDlg::SetChildCheck(HTREEITEM hTree, BOOL bCheck) { m_TreeCtrl.Expand(hTree,TVE_EXPAND); hTree = m_TreeCtrl.GetChildItem(hTree); //獲取子項句柄 while (hTree) { m_TreeCtrl.SetCheck(hTree, bCheck); SetChildCheck(hTree,bCheck); //遞歸調用 hTree = m_TreeCtrl.GetNextSiblingItem(hTree); //獲取兄弟的句柄 } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
void CTestTimerDlg::SetParentCheck(HTREEITEM hTree, BOOL bCheck) { HTREEITEM hParent = m_TreeCtrl.GetParentItem(hTree); if (hParent) { HTREEITEM hChild = m_TreeCtrl.GetChildItem(hParent); while (hChild) { if (hChild == hTree) { hChild = m_TreeCtrl.GetNextSiblingItem(hChild); continue ; } BOOL bflag = m_TreeCtrl.GetCheck(hChild); if (bCheck == bflag) //判斷是否還有兄弟項被選擇 { return ; } hChild = m_TreeCtrl.GetNextSiblingItem(hChild); } m_TreeCtrl.SetCheck(hParent,!bCheck); SetParentCheck(hParent,bCheck); //設置父項的狀態 } |