Attempt #1:
The first thing I looked for was some sort of property or method which could increase the scroll step. Nothing.
Attempt #2:
The next thing to try was take complete control of the scrolling. I put in my own scrollbar and handled the Scroll event of the scrollbar. This was a reasonable approach but then I realized that the Touch Flo scroll gesture did not work for me. I slapped my forehead and proceeded to the next attempt.
Attempt #3 (Final Solution):
The only other real solution was to take control of the Windows pumping messages. It turns out that you can override the WndProc function for Windows Forms. When it comes to the .NET Compact Framework, though, you can’t do that because its just not supported. I googled for an alternative and found this. I really must thank Mike Underhill for bailing me out here.
Third time’s a charm, they say and it seemed true in my case. This is what I ended up with.
private const int WM_VSCROLL = 0x115;
private const int GWL_WNDPROC = -4;
private const int SB_LINEUP = 0;
private const int SB_LINEDOWN = 1;
delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg,
IntPtr wParam, IntPtr lParam);
//Win32 APIs that I need.
[DllImport("coredll.dll", EntryPoint = "GetWindowLong")]
private static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("coredll.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newWndProc);
[DllImport("coredll.dll")]
static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd,
uint Msg, IntPtr wParam, IntPtr lParam);
private static IntPtr oldWndProc = IntPtr.Zero;
private static WndProcDelegate newWndProc;
private const long lowOrderMask = 0xF;
public IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
if (msg == WM_VSCROLL)
{
long val = ((long)wParam & lowOrderMask);
if (val == SB_LINEDOWN)
{
//Haven’t really found out why the Y position
//was going negative but this seemed an easy fix. :p
AutoScrollPosition =
new Point(0, - AutoScrollPosition.Y + step);
}
else if (val == SB_LINEUP)
{
AutoScrollPosition =
new Point(0, - AutoScrollPosition.Y - step);
}
return CallWindowProc(oldWndProc, hWnd, msg, wParam, lParam);
}
}
//Constructor
public Form1()
{
InitializeComponent();
newWndProc = new WndProcDelegate(WndProc);
oldWndProc = GetWindowLong(pnlContainer.Handle, GWL_WNDPROC);
SetWindowLong(pnlContainer.Handle, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(newWndProc));
}
Hope this helps someone who ever comes across this problem.
No comments:
Post a Comment