问题
There is a CListCtrl
with SetExtendedStyle (LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT)
, a single selection is false. I want to be able to select multiple lines with the mouse.
When starting selection from an empty area, it works:
It does not work if I start the selection not from an empty area. Selection frame does not appear:
How to make it work?
回答1:
It is not really a good idea to change how a common control works because users expect them to function like they do in all other applications.
The ListView (CListCtrl) does not support this feature but if you don't care about making non-dragging selections you can subclass the control and sort-of make it work:
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);
This code removes the full-row-select style and makes the first column "invisible" when the listview handles the initial mouse down message so that the internal listview hit-testing returns LVHT_NOWHERE and marquee-selection can start. You should consider this to be a ugly hack and I would recommend that you only intercept WM_LBUTTONDOWN
when Control or Shift is down...
来源:https://stackoverflow.com/questions/56619044/clistctrl-select-multiple-lines-with-the-mouse