2014-03-12 94 views
0

我的問題是,下面的函數被調用兩次:MFC樹控件通知觸發兩次

ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, &MainHamsterDlg::OnClickTree) 

void MainHamsterDlg::OnClickTree(NMHDR* pNMHDR, LRESULT* pResult) 
{ 
    CTreeCtrl* pCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE1); 
    HTREEITEM hItem = pCtrl->GetSelectedItem(); 
    BOOL hItemm = pCtrl->ItemHasChildren(hItem); 
    if (hItem && hItemm) 
    { 
     HTREEITEM hChild = pCtrl->GetChildItem(hItem); 
     pCtrl->SelectItem(hChild);       <--- Cause of the "loop" 
    } 

    *pResult = 1; 
} 

我需要我的代碼自動轉到樹的子元素。 (在將來,我會寫一些代碼來檢測一下已被選中,這將導致一些動作。)

我的代碼工作正常,當我點擊一個葉子,這是因爲:

if (hItem && hItemm) 

保證:

pCtrl->SelectItem(hChild); 

將不會被執行。如何在內部節點被點擊時使我的代碼工作?

回答

2

我知道這是一個骯髒的黑客攻擊,但它應該防止你的代碼被執行兩次。下面的成員添加到您的類:

bool ignoreNextSelChange = false; 

然後修改你的功能如下:

void MainHamsterDlg::OnClickTree(NMHDR* pNMHDR, LRESULT* pResult) 
{ 
    if (ignoreNextSelChange) 
    { 
     // Don't do anything, but make sure that the else block below will be executed 
     // again with the next (expected) call of this function. 
     ignoreNextSelChange = false; 
    } 
    else 
    { 
     CTreeCtrl* pCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE1); 
     HTREEITEM hItem = pCtrl->GetSelectedItem(); 
     BOOL hItemm = pCtrl->ItemHasChildren(hItem); 
     if (hItem && hItemm) 
     { 
      HTREEITEM hChild = pCtrl->GetChildItem(hItem); 

      // Make sure that this else block won't be executed again when the function 
      // SelectItem() is called below. 
      ignoreNextSelChange = true; 

      pCtrl->SelectItem(hChild); 
     } 
    } 
    *pResult = 1; 
} 
+0

是的,我正在考慮這個解決方案......也許我必須使用它..也許有人會寫出更好的解決方案,但現在對我來說還可以。 thx – Klasik

+0

對我而言,該解決方案效果更好 – Klasik

1

最終我找到了一些代碼,我解決了類似的問題。在代碼中,我處理TVN_SELCHANGING而不是TVN_SELCHANGED

ON_NOTIFY(TVN_SELCHANGING, IDC_TREE1, &MainHamsterDlg::OnSelChanging) 

void MainHamsterDlg::OnSelChanging(NMHDR* pNMHDR, LRESULT* pResult) 
{ 
    // Initially assume that the selection change is allowed. 
    *pResult = 0; 

    CTreeCtrl* pCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE1); 
    HTREEITEM hItem = pCtrl->GetSelectedItem(); 
    BOOL hItemm = pCtrl->ItemHasChildren(hItem); 
    if (hItem && hItemm) 
    { 
     // Set *pResult to TRUE to prevent the selection from changing. 
     *pResult = TRUE; 

     // Make an own selection. 
     HTREEITEM hChild = pCtrl->GetChildItem(hItem); 
     pCtrl->SelectItem(hChild); 
    } 
} 

調用在TVN_SELCHANGING消息處理程序SelectItem()不會引起我的問​​題。