Full DataGridView scrollbar code
public class ScrollDataGridView : DataGridView
{
private const int WM_HSCROLL = 0x0114,
WM_VSCROLL = 0x0115;
NativeScrollBar nsb;
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (this.Site == null)
{
this.nsb = new NativeScrollBar(this);
}
}
protected override void OnHandleDestroyed(EventArgs e)
{
base.OnHandleDestroyed(e);
if (this.nsb != null)
{
this.nsb.DestroyHandle();
}
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_VSCROLL:
if (m.LParam != this.VerticalScrollBar.Handle && this.VerticalScrollBar.Visible)
{
Control.ReflectMessage(this.VerticalScrollBar.Handle, ref m);
}
break;
case WM_HSCROLL:
if (m.LParam != this.HorizontalScrollBar.Handle && this.HorizontalScrollBar.Visible)
{
Control.ReflectMessage(this.HorizontalScrollBar.Handle, ref m);
}
break;
}
base.WndProc(ref m);
}
}
public class NativeScrollBar : NativeWindow
{
public NativeScrollBar(Control parent)
{
CreateParams cp = new CreateParams();
// Fill in the CreateParams details.
cp.Caption = String.Empty;
cp.ClassName = "SCROLLBAR";
// Set the position of the scrollbar so that it is offscreen
cp.X = -1000;
cp.Y = -1000;
cp.Height = 100;
cp.Width = 100;
// Create as a child of the specified parent
cp.Parent = parent.Handle;
cp.Style = WS_VISIBLE | SBS_VERT | WS_CHILD;
IntPtr modHandle = NativeScrollBar.GetModuleHandle(null);
IntPtr handleCreated = IntPtr.Zero;
int lastWin32Error = 0;
try
{
// Create the actual scrollbar window
handleCreated = NativeScrollBar.CreateWindowEx(cp.ExStyle, cp.ClassName,
cp.Caption, cp.Style, cp.X, cp.Y, cp.Width, cp.Height, new HandleRef(cp, cp.Parent), new HandleRef(null, IntPtr.Zero),
new HandleRef(null, modHandle), cp.Param);
lastWin32Error = Marshal.GetLastWin32Error();
}
catch (NullReferenceException e)
{
throw new OutOfMemoryException("Could not create Native Window");
}
if (handleCreated == IntPtr.Zero)
{
throw new Win32Exception(lastWin32Error, "System error creating Native Window");
}
// Now assign the NativeWindow handle to the native scroll bar
this.AssignHandle(handleCreated);
}
// Constant values were found in the "windows.h" header file.
private const int WS_CHILD = 0x40000000,
WS_VISIBLE = 0x10000000,
SBS_HORZ = 0x0000,
SBS_VERT = 0x0001;
[DllImport("USER32.DLL", EntryPoint = "CreateWindowEx", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CreateWindowEx(int dwExStyle, string lpszClassName,
string lpszWindowName, int style, int x, int y, int width, int height,
HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, [MarshalAs(UnmanagedType.AsAny)] object pvParam);
[DllImport("KERNEL32.DLL", CharSet = CharSet.Auto)]
private static extern IntPtr GetModuleHandle(string modName);
}