我的问题是以下函数被调用两次:
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);
不会被执行。如何在单击内部节点时使代码生效?
答案 0 :(得分: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;
}
答案 1 :(得分: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
并不会对我造成问题。