c++ - CListCtrl 用鼠标选择多行

标签 c++ winapi mfc clistctrl

有一个CListCtrlSetExtendedStyle (LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT),单个选择是错误的。我希望能够用鼠标选择多行。 当从空白区域开始选择时,它会起作用: enter image description here

如果我不是从空白区域开始选择,它将不起作用。不出现选择框: enter image description here

如何让它发挥作用?

最佳答案

改变通用控件的工作方式并不是一个好主意,因为用户希望它们像在所有其他应用程序中一样运行。

ListView (CListCtrl) 不支持此功能,但如果您不关心进行非拖动选择,您可以对控件进行子类化并对其进行排序:

WNDPROC g_OrgWndProc = 0;

static LRESULT CALLBACK LVSubClass(HWND hWnd, UINT Msg, WPARAM wp, LPARAM lp)
{
    if (Msg == WM_LBUTTONDOWN)
    {
        UINT oldexstyle = (UINT) ListView_SetExtendedListViewStyleEx(hWnd, LVS_EX_FULLROWSELECT, 0);
        LRESULT oldcolw = ListView_GetColumnWidth(hWnd, 0);
        ListView_SetColumnWidth(hWnd, 0, 0);
        PostMessage(hWnd, WM_APP, oldexstyle, oldcolw); // Restore delay
        return CallWindowProc(g_OrgWndProc, hWnd, Msg, wp, lp);
    }
    if (Msg == WM_APP)
    {
        ListView_SetExtendedListViewStyleEx(hWnd, LVS_EX_FULLROWSELECT, (UINT) wp);
        ListView_SetColumnWidth(hWnd, 0, (UINT) lp);
    }
    return CallWindowProc(g_OrgWndProc, hWnd, Msg, wp, lp);
}

...

g_OrgWndProc = (WNDPROC) SetWindowLongPtr(listviewhandle, GWLP_WNDPROC, (LONG_PTR) LVSubClass);

此代码删除了全行选择样式,并使第一列在 ListView 处理初始鼠标按下消息时“不可见”,以便内部 ListView HitTest 返回 LVHT_NOWHERE 并且选取框选择可以开始。您应该认为这是一个丑陋的黑客行为,我建议您仅在 ControlShift 关闭时拦截 WM_LBUTTONDOWN...

关于c++ - CListCtrl 用鼠标选择多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56619044/

相关文章:

c++ - 如何在 conanfile.txt 中设置编译器和 arch?

multithreading - 当回调返回时,LeaveCriticalSection有什么意义?

c++ - 顶行右对齐的 MFC 工具栏

c++ - 等到事件发生

c++ - boost 每个问题

c++ - 将 Mat 转换为 <vector<vector>> C++

c++ - 有if-else,有没有Neither Nor语句?

c++ - 我如何决定是否为新的 C++ 项目使用 ATL、MFC、Win32 或 CLR?

c++ - 如何从 Gdiplus::Bitmap 快速复制数据

c++ - MFC 的 Direct2D 透明度