vc 樹型控件中SetCheck()函數的使用

對於對話框中的TreeView控件,如果想在初始化(OnInitDialog)中SetCheck,必須:
m_tree.ModifyStyle( TVS_CHECKBOXES, 0 );
m_tree.ModifyStyle( 0, TVS_CHECKBOXES );
m_tree.SetCheck(hItem, TRUE);
即即使在對話框編輯器中爲TreeView增加了Check Boxes屬性,也必須重新設一次TVS_CHECKBOXES,SetCheck才能起作用
而對於非初始化中的SetCheck,則不受影響

出處:http://shuiyu.100steps.net/blog_old/index.php?job=art&articleid=a_20050303_225747

感覺此文作者盡心盡責,有關CTreeView的一些問題說的很詳細,也許我以後能用的着,所以先把他這篇文章放於下面,以便來日方便查看:

 

關於TreeView控件

關於TreeView控件
(1)SetCheck
   對於對話框中的TreeView控件,如果想在初始化(OnInitDialog)中SetCheck,必須:
m_tree.ModifyStyle( TVS_CHECKBOXES, 0 );
m_tree.ModifyStyle( 0, TVS_CHECKBOXES );
m_tree.SetCheck(hItem, TRUE);
即即使在對話框編輯器中爲TreeView增加了Check Boxes屬性,也必須重新設一次TVS_CHECKBOXES,SetCheck才能起作用
而對於非初始化中的SetCheck,則不受影響

(2)OnCheckChange
   對於TreeView中的checkbox,沒有對應的notify,必須自己處理
   參考msdn.microsoft.com,Q261289
   我的做法稍有不同:
我的做法稍有不同:
   第一步:繼承CTreeCtrl
   class CMyTreeCtrl : public CTreeCtrl
   
   二:
   增加WM_LBUTTONDOWN處理函數。包括:

代碼

.h:
// 定義自定義消息,用於通知父窗口

#define UM_CHECKSTATECHANGE (WM_USER + xxx)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point) ;
   
.cpp:
ON_WM_LBUTTONDOWN()

void CMyTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
TVHITTESTINFO tvHitInfo = { point.x, point.y } ;
HitTest(&tvHitInfo) ; // 測試擊鍵位置

if (tvHitInfo.flags & TVHT_ONITEMSTATEICON)
GetParent()->SendMessage(UM_CHECKSTATECHANGE,
WPARAM(GetDlgCtrlID()), LPARAM(tvHitInfo.hItem)) ;
// 通知父窗口

CTreeCtrl::OnLButtonDown(nFlags, point) ;
}

發現不能捕獲WM_LBUTTONUP?!原因不知,請各位指教
發送消息不能用PostMessage。原因請看第三步
由於只能捕獲WM_LBUTTONDOWN,將導致一個問題,即如果用戶在checkbox中按下,卻拖動鼠標在checkbox外放手,就會出現不一致情況,因爲checkbox是收到WM_LBUTTONUP才作出反應的
目前我還沒有很好的解決這個問題,只有一個弱智辦法,通過timer來“糾正”錯誤。同樣請各位指教

三:
在dialog中,處理UM_CHECKSTATECHANGE

代碼

.h:
afx_msg void OnCheckChange(UINT nID, HTREEITEM hItem) ;

.cpp:
ON_MESSAGE(UM_CHECKSTATECHANGE, OnCheckChange)

void CxxxDlg::OnCheckChange(UINT nID, HTREEITEM hItem)
{
switch (nID)
{
case IDC_TREEVIEW: // IDC_TREEVIEW:TreeView控件的ID
if (m_tree.GetCheck(hItem))
{ // original checked, now unchecked
// TODO: 增加Unchecked代碼
}
else
{ // original unchecked, now checked
// TODO: 增加Checked代碼
}

break ;
}
}


這裏要注意,(GetCheck(hItem) == TRUE)表示Unchecked,(GetCheck(hItem) == FALSE)表示Checked,原因在於在CMyTreeCtrl中捕獲的是WM_LBUTTONDOWN,OnCheckChange發生時,checkbox還未變化。基於同樣原因,第二步中不能使用PostMessage,而必須SendMessage,以免出錯
不能在最後增加m_tree.SetCheck()來解決第二步中提到的問題。
根本辦法在於設法捕獲WM_LBUTTONUP

與microsoft的做法相比:減少了獲取鼠標點擊位置和座標映射的代碼;CMyTreeCtrl可以獨立出來重用

(3)TreeView的子窗口
   在特殊的情況下,需要在TreeView中添加子窗口
   主要問題:當TreeView中內容發生變化時,將重繪客戶區,將子窗口也抹去(?!至於原因,又要請各位指教了),即使子窗口設爲TOPMOST
   我的方法:
   第一步:
   繼承CTreeCtrl:class CMyTreeCtrl : public CTreeCtrl
   處理WM_PAINT,同時通知父窗口:

代碼

.h:
#define UM_TREEREDRAW (WM_USER + xxx)
afx_msg void OnPaint();
.cpp:
ON_WM_PAINT()
void CMyTreeCtrl::OnPaint()
{
CTreeCtrl::OnPaint() ;
GetParent()->SendMessage(UM_TREEREDRAW, WPARAM(GetDlgCtrlID()), LPARAM(0)) ;
}



二:
處理UM_TREEREDRAW:

代碼

void CxxxDlg::OnTreeRedraw(UINT nID, LPARAM lParam)
{
switch (nID)
{
case IDC_TREEVIEW: // IDC_TREEVIEW:TreeView控件的ID
wndChild.RedrawWindow(NULL, NULL, RDW_INVALIDATE) ; // 強制重繪子窗口
break ;
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章