How do I detect horizontal scroll movement in Listview by mouse click, mouse scroll and keyboard ? There are similar topics like this. I've tried most of them but none worked so far.
Creating your own scrollbar is the only way i suppose.. Here it is the solution:
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);
}
};
Then you set maximum value for the scroll bar and make it visible:
lvNufus->myVScrollBar->Visible = totalItems > 20 ? true : false;
lvNufus->myVScrollBar->Maximum = totalItems > 20 ? (miktar - 20 + 1) : 1;
totalItems represents total amount of items added into myListView. And the value 20 represents items displayed in total. This is for vertical scroll.