如何在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 表示总共显示的项目。这是为了垂直滚动。
如何通过鼠标单击、鼠标滚动和键盘检测 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 表示总共显示的项目。这是为了垂直滚动。