如何在Listview中检测水平滚动移动?(适用于VS2015 C++/CLI)

How to detect horizontal scroll movement in Listview?(for VS2015 C++/CLI)

如何通过鼠标单击、鼠标滚动和键盘检测 Listview 中的水平滚动移动?有类似的话题。我已经尝试了其中的大部分,但 none 到目前为止都有效。

我认为创建自己的滚动条是唯一的方法。这是解决方案:

using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;

[DllImport("User32.dll")]
[returnvalue:MarshalAs(UnmanagedType::Bool)]
extern "C" System::Boolean ShowScrollBar(IntPtr hWnd, int wBar, bool bShow);
[DllImport("User32.dll")]
extern "C" System::Void SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

public ref class myListView : ListView
{
    public: myListView(void)
    {
        myVScrollBar = gcnew VScrollBar();
        myVScrollBar->Dock = DockStyle::Right;
        myVScrollBar->SmallChange = 1;
        myVScrollBar->LargeChange = 2;
        myVScrollBar->Minimum = 0;
        ViewableCount = 1;
        myVScrollBar->Visible = false;
        Wheeling = false;
        up = false;

        myVScrollBar->ValueChanged += gcnew EventHandler(this, &myListView::myVScrollBar_WheelChanged);
        myVScrollBar->Scroll += gcnew ScrollEventHandler(this, &myListView::myVScrollBar_ScrollChanged);
        Controls->Add(myVScrollBar);
    }

    private:
        int ViewableCount;
        bool Wheeling;
        bool up;

    public:
        VScrollBar^ myVScrollBar;

    [SecurityPermission(SecurityAction::Demand, Flags = SecurityPermissionFlag::UnmanagedCode)]
    virtual void WndProc(Message% m) override
    {
        ShowScrollBar(Handle, SB_VERT, false);
        __super::WndProc(m);

        switch (m.Msg)
        {
            case WM_MOUSEWHEEL:
            {
                Wheeling = true;
                up = (GET_WHEEL_DELTA_WPARAM(reinterpret_cast<int*>(m.WParam.ToPointer())) > 0);
                if (up)
                {
                    if (myVScrollBar->Value - ViewableCount > 0)
                        myVScrollBar->Value -= ViewableCount;
                    else
                        myVScrollBar->Value = 0;
                }
                else
                {
                    if (myVScrollBar->Value + myVScrollBar->LargeChange + ViewableCount <= myVScrollBar->Maximum)
                        myVScrollBar->Value += ViewableCount;
                    else
                        myVScrollBar->Value = 1 + myVScrollBar->Maximum - myVScrollBar->LargeChange;
                }
            }
            break;
            case WM_VSCROLL:
            {
                switch (m.WParam.ToInt32())
                {
                    case SB_PAGEUP:
                        if (myVScrollBar->Value - ViewableCount > 0)
                            myVScrollBar->Value -= ViewableCount-1;
                        else
                            myVScrollBar->Value = 0;
                        break;
                    case SB_PAGEDOWN:
                        if (myVScrollBar->Value + myVScrollBar->LargeChange + ViewableCount <= myVScrollBar->Maximum)
                            myVScrollBar->Value += ViewableCount-1;
                        break;
                }
            }
            break;
        }
    }

    private: System::Void myVScrollBar_WheelChanged(Object^ sender, EventArgs^ e)
    {
        if (!Wheeling)
            return;

        SendMessage(Handle, 0x1000 + 20, 0, up ? -10 : 10);
    }

    private: System::Void myVScrollBar_ScrollChanged(Object^ sender, ScrollEventArgs^ e)
    {
        Wheeling = false;

        if (e->OldValue == e->NewValue)
            return;

        int t = e->NewValue;
        int i = e->OldValue;
        if (e->OldValue > e->NewValue)
        {
            t = e->OldValue;
            i = e->NewValue;
        }
        for (i; i < t; ++i)
            SendMessage(Handle, 0x1000 + 20, 0, e->NewValue - e->OldValue > 0 ? 10 : -10);
    }
};

然后设置滚动条的最大值并使其可见:

lvNufus->myVScrollBar->Visible = totalItems > 20 ? true : false;
lvNufus->myVScrollBar->Maximum = totalItems > 20 ? (miktar - 20 + 1) : 1; 

totalItems 表示添加到 myListView 中的项目总数。值 20 表示总共显示的项目。这是为了垂直滚动。