我使用 WinApi 创建了一个 TreeView 控件。我想捕获鼠标点击复选框。通知消息NM_CLICK包含NMHDR,其中没有有关被单击的节点的信息。由于单击的节点可能与选定的节点不同,因此应该有一种方法可以找到已选中或未选中的节点,可以是HTREEITEM,也可以是在向 TreeView 添加项目时插入的lParam。我想实时捕获检查/取消检查。如何指定选中/取消选中哪个节点?任何帮助或链接表示赞赏。 阿布扎德先生
最佳答案
I want to capture the checking/unchecking in real time. How can I specify which Node being checked/unchecked?
对于此存在通知 TVN_ITEMCHANGING和 TVN_ITEMCHANGED - 查找 NMTVITEMCHANGE
的 uStateNew
和 uStateOld
成员- 当 TreeView 有复选框(TVS_CHECKBOXES
样式)时,它用作带有 2 个图像的状态图像列表 - 未选中
和 已选中
。
因此,当没有复选框时,state & TVIS_STATEIMAGEMASK
将为 0
,未选中时为 INDEXTOSTATEIMAGEMASK(1)
,而 INDEXTOSTATEIMAGEMASK(2)
进行检查。基于此信息,我们可以捕获鼠标点击复选框
通过使用TVN_ITEMCHANGING您还可以在为此通知返回 TRUE 时阻止更改。如果您只需要通知 - 使用 TVN_ITEMCHANGED
case WM_NOTIFY:
{
union {
LPARAM lp;
NMTVITEMCHANGE *pnm;
NMHDR* phdr;
};
lp = lParam;
switch (phdr->code)
{
case TVN_ITEMCHANGING:
{
UINT CheckStateOld = pnm->uStateOld & TVIS_STATEIMAGEMASK;
UINT CheckStateNew = pnm->uStateNew & TVIS_STATEIMAGEMASK;
if (CheckStateNew != CheckStateOld)
{
PCSTR szstate = "??";
switch (CheckStateNew)
{
case INDEXTOSTATEIMAGEMASK(1):
szstate = "uncheck";
break;
case INDEXTOSTATEIMAGEMASK(2):
szstate = "check";
break;
}
DbgPrint("%p>%s\n", pnm->lParam, szstate);
}
}
return FALSE;
}
}
<小时/>
另请阅读How to Work With State Image Indexes
<小时/>// Image 1 in the tree-view check box image list is the unchecked box. // Image 2 is the checked box. tvItem.state = INDEXTOSTATEIMAGEMASK((fCheck ? 2 : 1));
通知TVN_ITEMCHANGING和 TVN_ITEMCHANGED从 Windows Vista 开始可用。如果您也需要 XP 支持 - 仅在 xp 选项上使用 @IInspectable solution
关于c - 如何捕获哪个 TreeView 节点被单击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41434832/