我有一个树控件,Tree控件由一个Root节点组成
并且该根节点由一个子节点组成,该子节点由3个节点组成。
这个树控件位于一个属性页面上,在我点击任何一个复选框之后
启用向导按钮。在TVN_ITEMCHANGED
的事件处理程序中,我启用了工作表
的按钮。
当我运行我的应用程序并检查treecontrol节点后,我无法启用
表单按钮。我已经看到代码绝对正常,我正在检查节点的检查状态
并启用工作表按钮。我开始调试我的代码,首先是NM_CLICK
被解雇了
然后我期待TVN_ITEMCHANGED
事件被解雇,但它根本没有被解雇。
我不知道为什么这个事件没有被解雇,我使用的环境是WindowsXP
。
我在windows7
,windows 8
,windows vista
上运行了我的应用程序。它正在按预期工作,但仅在XP中
我发现了这种行为。
任何人都可以帮我解决这个问题。
答案 0 :(得分:5)
根据MSKB,您在点击该复选框时未收到特定通知。
在具有TVS_CHECKBOXES样式的TreeView控件上,没有 通知已检查项目的状态已更改。 也没有通知表明状态 项目已更改。但是,您可以确定用户已单击 该项目的状态图标并对此采取行动。
引用该文章:
当用户单击TreeView项目的复选框时,NM_CLICK 通知发送到父窗口。当发生这种情况时, TVM_HITTEST消息返回TVHT_ONITEMSTATEICON。 TreeView控件 使用相同的条件来切换复选框的状态。 不幸的是,TreeView控件切换后的状态 发送NM_CLICK通知。
您可以将用户定义的消息发布到同一窗口 处理NM_CLICK通知,并处理此用户定义 消息作为已检查状态已更改的通知。 以下示例代码说明了这可能是什么 完成的:
使用相关的示例代码:
#define UM_CHECKSTATECHANGE (WM_USER + 100)
case WM_NOTIFY:
{
LPNMHDR lpnmh = (LPNMHDR) lParam;
TVHITTESTINFO ht = {0};
if(lpnmh->code == NM_CLICK) && (lpnmh->idFrom == IDC_MYTREE))
{
DWORD dwpos = GetMessagePos();
// include <windowsx.h> and <windows.h> header files
ht.pt.x = GET_X_LPARAM(dwpos);
ht.pt.y = GET_Y_LPARAM(dwpos);
MapWindowPoints(HWND_DESKTOP, lpnmh->hwndFrom, &ht.pt, 1);
TreeView_HitTest(lpnmh->hwndFrom, &ht);
if(TVHT_ONITEMSTATEICON & ht.flags)
{
PostMessage(hWnd, UM_CHECKSTATECHANGE, 0, (LPARAM)ht.hItem);
}
}
}
break;
case UM_CHECKSTATECHANGE:
{
HTREEITEM hItemChanged = (HTREEITEM)lParam;
/*
Retrieve the new checked state of the item and handle the notification.
*/
}
break;