Bee Eee Blog

Archive for January 4th, 2008

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 Comment more...

Making a UserControl a design time container for controls.

by brian on Jan.04, 2008, under Uncategorized

It turns out that a user control can fairly easily become a container control during design time. In other words being able to put other controls within your user control is fairly straight forward.

The steps are as follows.

add the following to your usings section:

using System.ComponentModel.Design;

and then add the following attribute just above your declared class.

[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]

public class UserControl1 : System.Windows.Forms.UserControl

{
...
}

Then recompile the project and there it is.

Leave a Comment more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...