无法使用互斥复选框实现树形视图

3

我需要实现一个具有以下行为的树形视图:

当用户勾选一个项目时,之前勾选的项目将取消勾选。我不是母语为英语的人,但我了解这种行为被称为“互斥复选框”。

我发现了似乎适合我的需求的TVS_EX_EXCLUSIONCHECKBOXES扩展样式,但我无法成功使用它。

我通过使用SetWindowLongPtr而不是像MSDN建议的直接传递给CreateWindowEx来正确地设置TVS_CHECKBOXES样式。然后我使用GetWindowLongPtrSetWindowLongPtr来添加上面提到的扩展样式。代码编译通过,但运行时好像我从未添加过扩展样式。

  • 我已经链接了commctrl库并启用了视觉样式;
  • 我已经初始化了公共控件;

下面是WM_CREATE处理程序。

case WM_CREATE:
{
    HWND hwndTV = CreateWindowEx(0, WC_TREEVIEW, L"tv", 
        WS_CHILD | WS_VISIBLE | WS_BORDER | 
        TVS_FULLROWSELECT | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT,
        50, 50, 150, 250, hWnd, (HMENU)4000, hInst, 0);

    // add checkbox

    DWORD dwStyle = GetWindowLongPtr(hwndTV, GWL_STYLE), 
        dwExStyle = GetWindowLongPtr(hwndTV, GWL_EXSTYLE);

    dwStyle |= TVS_CHECKBOXES;
    dwExStyle |= TVS_EX_EXCLUSIONCHECKBOXES;
    
    SetWindowLongPtr(hwndTV, GWL_STYLE, dwStyle);
    SetWindowLongPtr(hwndTV, GWL_EXSTYLE, dwExStyle);

    TVINSERTSTRUCT tvis = { 0 };
    
    tvis.item.mask = TVIF_TEXT;
    tvis.item.pszText = L"ROOT ITEM 1";
    HTREEITEM root1 = TreeView_InsertItem(hwndTV, &tvis);

    tvis.item.mask = TVIF_TEXT;
    tvis.item.pszText = L"ROOT ITEM 2";
    HTREEITEM root2 = TreeView_InsertItem(hwndTV, &tvis);

    tvis.item.mask = TVIF_TEXT;
    tvis.item.pszText = L"First child";
    tvis.hParent = root1;
    tvis.hInsertAfter = TVI_FIRST;
    HTREEITEM child1 = TreeView_InsertItem(hwndTV, &tvis);
}

问题:

我是否误解了关于TVS_EX_EXCLUSIONCHECKBOXES的文档?

  • 如果没有,那么我的代码应该如何修改才能按照我之前描述的方式运行?
  • 如果是,那么请告诉我。

给未来的读者:在设置 TVS_CHECKBOXES 样式之前,必须先调用 TreeView_SetExtendedStyle 函数! - AlwaysLearningNewStuff
TVS_EX_EXCLUSIONCHECKBOXES 是否确实实现了你所期望的功能? - Jonathan Potter
@JonathanPotter:不,它不行。我猜唯一的方法就是你之前推荐给我的那个... - AlwaysLearningNewStuff
Raymond Chen 解释了这种风格的工作原理:https://devblogs.microsoft.com/oldnewthing/20171205-00/?p=97525 而这种风格并不是 OP 想要的。 - 4LegsDrivenCat
1个回答

4

TVS_EX_xxx 样式并不是“扩展窗口样式”,而是“扩展树形视图样式”。它们只能通过 TVM_SETEXTENDEDSTYLE 消息进行设置。

TreeView_SetExtendedStyle(hwndTV,
           TVS_EX_EXCLUSIONCHECKBOXES, TVS_EX_EXCLUSIONCHECKBOXES);

感谢您回答,波特先生。我已经复制/粘贴了您的代码,但仍然无法获得所需的行为。我已经检查了“TreeView_SetExtendedStyle”的返回代码,并且没有报告错误。我应该编辑我的帖子以重新编写代码,还是您会自己开始解决这个问题? - AlwaysLearningNewStuff
我怀疑 TVS_EX_EXCLUSIONCHECKBOXES 并不是你想象中的那样。实际上,我不知道它具体有什么作用;我从未使用过它,而且似乎也没有相关文档记录。 - Jonathan Potter
是的,我之前通过引入 static 变量来实现了这个功能。我只是想尝试一下这种方式,以便可以去掉 static 变量... - AlwaysLearningNewStuff
好的,也许 Raymond Chen 会路过并愿意与我们分享他的知识... :) - Jonathan Potter
1
波特先生,我已经决定授予您悬赏,因为我怀疑其他人不会提供替代方案。虽然您的答案没有解决我的问题,但我很感激您愿意阅读我的问题以及试图解决它的善意。最好的问候和新年快乐。 - AlwaysLearningNewStuff
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接