MFC树控制通知触发两次
MFC tree control notification is triggered twice
我的问题是下面的函数被调用了两次:
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);
不会被执行。当单击内部节点时,如何使代码工作?
我知道这是一个肮脏的hack,但它应该防止你的代码被执行两次。向类中添加以下成员:
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;
}
最后我找到了一些代码,在那里我解决了一个类似的问题。在该代码中,我处理了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()
不会对我造成问题。
相关文章:
- g++的分段错误(在NaN上使用to_string两次时)
- 蛇在C++不会连续转两次
- 检查一个数组是否包含在另一个数组中,以相反的顺序,至少两次
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 我应该如何去缓解两次出现的cin?
- Realloc 两次无法在 Visual Studio 上运行
- 使用 getline(cin, var) 两次在进行字符串比较时会产生错误 (==)
- 按 Tab 单步执行两个控制组
- 为什么映射插入和 map.find() 的单次迭代比插入和 map.find() 的两次单独迭代慢得多
- C++析构函数调用两次,堆栈分配的复合对象
- 为什么参数在构造 std::thread 时移动两次
- Qt插槽调用了两次
- 做 std::用相同的unique_ptr移动两次
- C++两次定义相同的函数会导致错误
- 为什么具有静态存储持续时间的同一内联变量在包含在 VS2017 编译的两个翻译单元中时会构造和销毁两次
- 对于优化级别为 0 的 std::vector,析构函数被调用两次
- 使用柯南打包时如何避免列出两次依赖?
- 为什么要执行两次位移((x >> 4)<< 4)?
- 函数在控制台中运行两次
- MFC树控制通知触发两次