CListCtrl用鼠标选择多行

时间:2019-06-16 12:56:54

标签: c++ winapi mfc clistctrl

有一个CListCtrlSetExtendedStyle (LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT),单个选择为false。我希望能够用鼠标选择多行。 从空白区域开始选择时,它可以工作: enter image description here

如果我不是从空白区域开始选择,那是行不通的。选择框不出现: enter image description here

如何使其工作?

1 个答案:

答案 0 :(得分:2)

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

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);

此代码删除了全行选择样式,并在列表视图处理最初的鼠标按下消息时使第一列“不可见”,以便内部列表视图命中测试返回LVHT_NOWHERE并可以开始进行选取框选择。您应该认为这是一个丑陋的骇客,我建议您仅在 Control Shift 关闭时才拦截WM_LBUTTONDOWN ...