C# capture the mouse — Get a global hook on the mouse.
by brian on Jan.04, 2008, under .NET, GUI, c#, coding
I’m developing a component that is like the sidebar in the Visual C# Express (c). To get it to appear when the mouse is over the control isn’t a problem, however I soon discovered that using the MouseEnter and MouseLeave didn’t work. When I went over child controls the MouseLeave would be called and cause my sidebar to collapse.
Instead I had to create a global mouse hook so that no matter what control the mouse was over I could get a mouse event.
First was the code to import the hook function:
// create a mouse over eventstatic int WH_MOUSE_LL = 14;
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern IntPtr GetModuleHandle(string moduleName);
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int UnhookWindowsHookEx(IntPtr hhook);
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, uint wParam, IntPtr lParam);
delegate IntPtr HookProc(int nCode, uint wParam, IntPtr lParam);
private HookProc hookProc;
private IntPtr hook;
Here is the event handler
IntPtr LowLevelMouseProc(int nCode, uint wParam, IntPtr lParam)
{
// get the current mouse position
Point p = Cursor.Position;
// convert to client rectangle to screen position
Rectangle r = RectangleToScreen(ClientRectangle);
// check to see if mouse is within control bounds
bool exp = (p.Y > r.Top && p.Y < r.Bottom && p.X > r.Left && p.X < r.Right);
// adjust the expansion
if (exp != Expanded)
Expanded = exp;
// Finished with this
return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);
}
Then the initialization code I put in the OnLoad event handler:
if (!DesignMode)
{
hookProc = new HookProc(LowLevelMouseProc);
hook = SetWindowsHookEx(WH_MOUSE_LL, hookProc, GetModuleHandle(null), 0);
}
And then code for closing in the OnHandleDestroyed event handler:
protected override void OnHandleDestroyed(EventArgs e)
{
UnhookWindowsHookEx(hook);
base.OnHandleDestroyed(e);
}
That should just about do it then. Now the UserControl can sense whether the mouse is overhead whether or not the mouse is over a child control.
Leave a Reply
You must be logged in to post a comment.
