1

我的问题是以下函数被调用了两次:

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);

不会被执行。单击内部节点时,如何使我的代码工作?

4

2 回答 2

3

我知道这是一个肮脏的黑客,但它应该可以防止你的代码被执行两次。将以下成员添加到您的班级:

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;
}
于 2014-03-12T13:48:32.337 回答
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);
    }
}

调用消息处理程序不会对我造成问题SelectItem()TVN_SELCHANGING

于 2014-03-12T15:28:06.397 回答