【问题标题】:CListCtrl select multiple lines with the mouseCListCtrl 用鼠标选择多行
【发布时间】:2019-06-16 12:56:54
【问题描述】:

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

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

如何让它发挥作用?

【问题讨论】:

  • 这是因为默认的拖放行为(参见Default List-View Message Processing)。我不知道关闭此功能的专用方法,也许您可​​以通过覆盖WM_NCHITTEST 和/或WM_LBUTTONDOWN 来实现它。
  • 这就是列表视图的工作方式,如果您单击一个项目,您只会选择该项目。如果你想画套索,你必须点击一个项目。

标签: c++ winapi mfc clistctrl


【解决方案1】:

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

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 并且可以开始选取框。你应该认为这是一个丑陋的黑客,我建议你只在 ControlShift 关闭时拦截WM_LBUTTONDOWN...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 2014-12-19
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    相关资源
    最近更新 更多