Как обнаружить горизонтальное движение прокрутки в Listview? (Для VS2015 C ++ / CLI) - PullRequest
0 голосов
/ 11 марта 2020

Как определить горизонтальное движение прокрутки в Listview с помощью щелчка мыши, прокрутки мыши и клавиатуры? Есть похожие темы, подобные этой. Я пробовал большинство из них, но пока никто не работал.

1 Ответ

0 голосов
/ 18 марта 2020

Создание собственной полосы прокрутки - единственный способ, которым я полагаю. Вот решение:

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 представляет элементы, отображаемые в общей сложности. Это для вертикальной прокрутки.

...