using System;
namespace OpenCTT{
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices ;
public class ScrollablePanel: System.Windows.Forms.Panel
{
public event System.Windows.Forms.ScrollEventHandler ScrollHorizontal;
public event System.Windows.Forms.ScrollEventHandler ScrollVertical;
public event System.Windows.Forms.MouseEventHandler ScrollMouseWheel;
private const int SB_LINEUP = 0;
private const int SB_LINEDOWN = 1;
private const int SB_PAGEUP = 2;
private const int SB_PAGEDOWN = 3;
private const int SB_THUMBPOSITION = 4;
private const int SB_THUMBTRACK = 5;
private const int SB_TOP = 6;
private const int SB_BOTTOM = 7;
private const int SB_ENDSCROLL = 8;
private const int WM_HSCROLL = 0x114;
private const int WM_VSCROLL = 0x115;
private const int WM_MOUSEWHEEL = 0x020A;
private const int WM_NCCALCSIZE =0x0083;
private const int WM_PAINT =0x000F;
private const int WM_SIZE =0x0005;
private const uint SB_HORZ = 0;
private const uint SB_VERT = 1;
private const uint SB_CTL = 2;
private const uint SB_BOTH = 3;
private const uint ESB_DISABLE_BOTH = 0x3;
private const uint ESB_ENABLE_BOTH = 0x0;
private const int MK_LBUTTON = 0x01;
private const int MK_RBUTTON = 0x02;
private const int MK_SHIFT = 0x04;
private const int MK_CONTROL = 0x08;
private const int MK_MBUTTON = 0x10;
private const int MK_XBUTTON1 = 0x0020;
private const int MK_XBUTTON2 = 0x0040;
private bool enableAutoHorizontal = true;
private bool enableAutoVertical = true;
private bool visibleAutoHorizontal = true;
private bool visibleAutoVertical = true;
private int autoScrollHorizontalMinimum = 0;
private int autoScrollHorizontalMaximum = 100;
private int autoScrollVerticalMinimum = 0;
private int autoScrollVerticalMaximum = 100;
public ScrollablePanel()
{
this.Click += new EventHandler(ScrollablePanel_Click);
this.AutoScroll = true;
}
public int AutoScrollHPos
{
get { return GetScrollPos(this.Handle, (int)SB_HORZ); }
set { SetScrollPos(this.Handle, (int)SB_HORZ, value, true); }
}
public int AutoScrollVPos
{
get { return GetScrollPos(this.Handle, (int)SB_VERT); }
set { SetScrollPos(this.Handle, (int)SB_VERT, value, true); }
}
public int AutoScrollHorizontalMinimum
{
get { return this.autoScrollHorizontalMinimum; }
set
{
this.autoScrollHorizontalMinimum = value;
SetScrollRange(this.Handle, (int)SB_HORZ, autoScrollHorizontalMinimum, autoScrollHorizontalMaximum, true);
}
}
public int AutoScrollHorizontalMaximum
{
get { return this.autoScrollHorizontalMaximum; }
set
{
this.autoScrollHorizontalMaximum = value;
SetScrollRange(this.Handle, (int)SB_HORZ, autoScrollHorizontalMinimum, autoScrollHorizontalMaximum, true);
}
}
public int AutoScrollVerticalMinimum
{
get { return this.autoScrollVerticalMinimum; }
set
{
this.autoScrollVerticalMinimum = value;
SetScrollRange(this.Handle, (int)SB_VERT, autoScrollHorizontalMinimum, autoScrollHorizontalMaximum, true);
}
}
public int AutoScrollVerticalMaximum
{
get { return this.autoScrollVerticalMaximum; }
set
{
this.autoScrollVerticalMaximum = value;
SetScrollRange(this.Handle, (int)SB_VERT, autoScrollHorizontalMinimum, autoScrollHorizontalMaximum, true);
}
}
public bool EnableAutoScrollHorizontal
{
get { return this.enableAutoHorizontal; }
set
{
this.enableAutoHorizontal = value;
if (value)
EnableScrollBar(this.Handle, SB_HORZ, ESB_ENABLE_BOTH);
else
EnableScrollBar(this.Handle, SB_HORZ, ESB_DISABLE_BOTH);
}
}
public bool EnableAutoScrollVertical
{
get { return this.enableAutoVertical; }
set
{
this.enableAutoVertical = value;
if (value)
EnableScrollBar(this.Handle, SB_VERT, ESB_ENABLE_BOTH);
else
EnableScrollBar(this.Handle, SB_VERT, ESB_DISABLE_BOTH);
}
}
public bool VisibleAutoScrollHorizontal
{
get { return this.visibleAutoHorizontal; }
set
{
this.visibleAutoHorizontal = value;
ShowScrollBar(this.Handle, (int)SB_HORZ, value);
}
}
public bool VisibleAutoScrollVertical
{
get { return this.visibleAutoVertical; }
set
{
this.visibleAutoVertical = value;
ShowScrollBar(this.Handle, (int)SB_VERT, value);
}
}
private int getSBFromScrollEventType(ScrollEventType type)
{
int res = -1;
switch (type)
{
case ScrollEventType.SmallDecrement:
res = SB_LINEUP;
break;
case ScrollEventType.SmallIncrement:
res = SB_LINEDOWN;
break;
case ScrollEventType.LargeDecrement:
res = SB_PAGEUP;
break;
case ScrollEventType.LargeIncrement:
res = SB_PAGEDOWN;
break;
case ScrollEventType.ThumbTrack:
res = SB_THUMBTRACK;
break;
case ScrollEventType.First:
res = SB_TOP;
break;
case ScrollEventType.Last:
res = SB_BOTTOM;
break;
case ScrollEventType.ThumbPosition:
res = SB_THUMBPOSITION;
break;
case ScrollEventType.EndScroll:
res = SB_ENDSCROLL;
break;
default:
break;
}
return res;
}
private ScrollEventType getScrollEventType(System.IntPtr wParam)
{
ScrollEventType res = 0;
switch (LoWord((int)wParam))
{
case SB_LINEUP:
res = ScrollEventType.SmallDecrement;
break;
case SB_LINEDOWN:
res = ScrollEventType.SmallIncrement;
break;
case SB_PAGEUP:
res = ScrollEventType.LargeDecrement;
break;
case SB_PAGEDOWN:
res = ScrollEventType.LargeIncrement;
break;
case SB_THUMBTRACK:
res = ScrollEventType.ThumbTrack;
break;
case SB_TOP:
res = ScrollEventType.First;
break;
case SB_BOTTOM:
res = ScrollEventType.Last;
break;
case SB_THUMBPOSITION:
res = ScrollEventType.ThumbPosition;
break;
case SB_ENDSCROLL:
res = ScrollEventType.EndScroll;
break;
default:
res = ScrollEventType.EndScroll;
break;
}
return res;
}
protected override void WndProc(ref Message msg)
{
base.WndProc(ref msg);
if (msg.HWnd != this.Handle)
return;
switch (msg.Msg)
{
case WM_MOUSEWHEEL:
if (!this.VisibleAutoScrollVertical)
return;
try
{
int zDelta = HiWord((int)msg.WParam);
int y = HiWord((int)msg.LParam);
int x = LoWord((int)msg.LParam);
System.Windows.Forms.MouseButtons butt;
switch (LoWord((int)msg.WParam))
{
case MK_LBUTTON:
butt = System.Windows.Forms.MouseButtons.Left;
break;
case MK_MBUTTON:
butt = System.Windows.Forms.MouseButtons.Middle;
break;
case MK_RBUTTON:
butt = System.Windows.Forms.MouseButtons.Right;
break;
case MK_XBUTTON1:
butt = System.Windows.Forms.MouseButtons.XButton1;
break;
case MK_XBUTTON2:
butt = System.Windows.Forms.MouseButtons.XButton2;
break;
default:
butt = System.Windows.Forms.MouseButtons.None;
break;
}
System.Windows.Forms.MouseEventArgs arg0 = new System.Windows.Forms.MouseEventArgs(butt, 1, x, y, zDelta);
this.ScrollMouseWheel(this, arg0);
}
catch (Exception) { }
break;
case WM_VSCROLL:
try
{
ScrollEventType type = getScrollEventType(msg.WParam);
ScrollEventArgs arg = new ScrollEventArgs(type, GetScrollPos(this.Handle, (int)SB_VERT));
this.ScrollVertical(this, arg);
}
catch (Exception) { }
break;
case WM_HSCROLL:
try
{
ScrollEventType type = getScrollEventType(msg.WParam);
ScrollEventArgs arg = new ScrollEventArgs(type, GetScrollPos(this.Handle, (int)SB_HORZ));
this.ScrollHorizontal(this, arg);
}
catch (Exception) { }
break;
default:
break;
}
}
public void performScrollHorizontal(ScrollEventType type)
{
int param = getSBFromScrollEventType(type);
if (param == -1)
return;
SendMessage(this.Handle, (uint)WM_HSCROLL, (System.UIntPtr)param, (System.IntPtr)0);
}
public void performScrollVertical(ScrollEventType type)
{
int param = getSBFromScrollEventType(type);
if (param == -1)
return;
SendMessage(this.Handle, (uint)WM_VSCROLL, (System.UIntPtr)param, (System.IntPtr)0);
}
private void ScrollablePanel_Click(object sender, EventArgs e)
{
this.Focus();
}
[DllImport("user32.dll", CharSet=CharSet.Auto)]
static public extern int GetSystemMetrics(int code);
[DllImport("user32.dll")]
static public extern bool EnableScrollBar(System.IntPtr hWnd, uint wSBflags, uint wArrows);
[DllImport("user32.dll")]
static public extern int SetScrollRange(System.IntPtr hWnd, int nBar, int nMinPos, int nMaxPos, bool bRedraw);
[DllImport("user32.dll")]
static public extern int SetScrollPos(System.IntPtr hWnd, int nBar, int nPos, bool bRedraw);
[DllImport("user32.dll")]
static public extern int GetScrollPos(System.IntPtr hWnd, int nBar);
[DllImport("user32.dll")]
static public extern bool ShowScrollBar(System.IntPtr hWnd, int wBar, bool bShow);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static extern int HIWORD(System.IntPtr wParam);
static int MakeLong(int LoWord, int HiWord)
{
return (HiWord << 16) | (LoWord & 0xffff);
}
static IntPtr MakeLParam(int LoWord, int HiWord)
{
return (IntPtr) ((HiWord << 16) | (LoWord & 0xffff));
}
static int HiWord(int number)
{
if ((number & 0x80000000) == 0x80000000)
return (number >> 16);
else
return (number >> 16) & 0xffff ;
}
static int LoWord(int number)
{
return number & 0xffff;
}
}
}
|