c - 如何捕获哪个 TreeView 节点被单击

标签 c winapi treeview

我使用 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_ITEMCHANGINGTVN_ITEMCHANGED - 查找 NMTVITEMCHANGEuStateNewuStateOld 成员- 当 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_ITEMCHANGINGTVN_ITEMCHANGED从 Windows Vista 开始可用。如果您也需要 XP 支持 - 仅在 xp 选项上使用 @IInspectable solution

关于c - 如何捕获哪个 TreeView 节点被单击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41434832/

相关文章:

c++ - 为什么用非常量声明静态变量不会在g++中给出错误

c - strtok 中的段错误

c - VS 代码 : include file not found in browse. 路径。?

c++ - win32 应用程序是否只有一个消息循环?还是每个窗口一个消息循环?

c - 在C语言中使用 "GetAsyncKeyState(VK_UP)"和...

excel - 从kernel32调用writefile的vba dll创建了巨大的文件

wpf TreeViewItem BringIntoView 并不总是有效

c++ - 如何阻止时间在 Linux 上倒退?

javascript - Kendo TreeView - 仅将删除图像图标添加到没有子节点的父节点

c# - 如何从 subview 模型绑定(bind)到父 View 模型中的事件