// Author: Arman Ghazanchyan
// Created: 11/02/2006
// Modified: 09/12/2010
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Reflection;
namespace WindowsHookLib
{
#region ' Enumarations '
/// <summary>
/// Represents mouse coordinate mapping enumatation.
/// </summary>
public enum MapOn : int
{
/// <summary>
/// Maps the mouse coordinates relative to the previous mouse event (the last reported position).
/// Positive values mean the mouse moved right (or down); negative values mean the mouse moved left (or up).
/// </summary>
Relative = 0,
/// <summary>
/// Maps the absolute coordinates of the mouse on the screen.
/// In a multimonitor system, the coordinates map to the primary monitor.
/// </summary>
PrimaryMonitor = (int)UnsafeNativeMethods.MOUSEEVENTF_ABSOLUTE,
/// <summary>
/// Maps the mouse coordinates to the entire virtual desktop (multimonitor system).
/// </summary>
VirtualDesktop = (int)(UnsafeNativeMethods.MOUSEEVENTF_ABSOLUTE | UnsafeNativeMethods.MOUSEEVENTF_VIRTUALDESK)
}
#endregion
/// <summary>
/// Provides functionality to hook the mouse system wide (low level).
/// </summary>
[DebuggerNonUserCode]
[DefaultEvent("MouseClick"), ToolboxBitmap(typeof(MouseHook), "Resources.mouse"),
Description("Component that hooks the mouse system wide and raises some useful"
+ " events. The class provides methods to synthesize mouse events system wide.")]
public partial class MouseHook : Component
{
#region ' Event Handlers and Delegates '
/// <summary>
/// Occurs when the MouseHook state changed.
/// </summary>
[Description("Occurs when the MouseHook state changed.")]
public event System.EventHandler<WindowsHookLib.StateChangedEventArgs> StateChanged;
/// <summary>
/// Occurs when a mouse button is down.
/// </summary>
[Description("Occurs when a mouse button is down.")]
public event System.EventHandler<WindowsHookLib.MouseEventArgs> MouseDown;
/// <summary>
/// Occurs when the mouse pointer is moved.
/// </summary>
[Description("Occurs when the mouse pointer is moved.")]
public event System.EventHandler<WindowsHookLib.MouseEventArgs> MouseMove;
/// <summary>
/// Occurs when a mouse button is up.
/// </summary>
[Description("Occurs when a mouse button is up.")]
public event System.EventHandler<WindowsHookLib.MouseEventArgs> MouseUp;
/// <summary>
/// Occurs when the mouse wheel is rotated.
/// </summary>
[Description("Occurs when the mouse wheel is rotated.")]
public event System.EventHandler<WindowsHookLib.MouseEventArgs> MouseWheel;
/// <summary>
/// Occurs when a mouse button is clicked.
/// </summary>
[Description("Occurs when a mouse button is clicked.")]
public event System.Windows.Forms.MouseEventHandler MouseClick;
/// <summary>
/// Occurs when a mouse button is double clicked.
/// </summary>
[Description("Occurs when a mouse button is double clicked.")]
public event System.Windows.Forms.MouseEventHandler MouseDoubleClick;
/// <summary>
/// Represents the method that will handle the mouse message event.
/// </summary>
delegate IntPtr MouseMessageEventHandler(Int32 nCode, IntPtr wParam, ref UnsafeNativeMethods.MouseInfo lParam);
#endregion
#region ' Members '
//Holds a method pointer to MouseProc for callback.
//Needed for InstallHook method.
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[MarshalAs(UnmanagedType.FunctionPtr)]
private MouseHook.MouseMessageEventHandler _mouseProc;
//Holds the mouse hook handle. Needed
//for RemoveHook and MouseProc methods.
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private IntPtr _hMouseHook;
//Holds the mouse clicks. Needed for mouse
//click and mouse double click events.
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private int _clicks;
//Holds the mouse button that is currently down or up.
//Needed for mouse click and mouse double click events.
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private MouseButtons _button;
//A rectangle that contains the double click area.
//Needed for double click event.
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private Rectangle _rectangle;
//Holds a control handle that the mouse was on previously.
//Needed for mouse down and mouse up events.
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private IntPtr _hwnd;
//Holds bitwise combination of mouse buttons that
//are down. Needed for mouse move EventArgs object.
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private MouseButtons _buttonsDown;
//Control handle that the mouse event is associated.
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private IntPtr _cHandle;
//Holds the time between the clicks (determining doubleClicks).
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private static UInt32 this_time;
#endregion
#region ' Properties '
/// <summary>
/// Gets the component's assembly information.
/// </summary>
public static Assembly AssemblyInfo
{
get
{
return Assembly.GetExecutingAssembly();
}
}
/// <summary>
/// Gets the state of the hook.
/// </summary>
public HookState State
{
get
{
if (this._hMouseHook != IntPtr.Zero)
return HookState.Installed;
else
return HookState.Uninstalled;
}
}
#endregion
#region ' Methods '
/// <summary>
/// Default constructor.
/// </summary>
public MouseHook()
{
InitializeComponent();
this._rectangle = new Rectangle(0, 0,
SystemInformation.DoubleClickSize.Width,
SystemInformation.DoubleClickSize.Height);
}
private MouseHook(IContainer container)
{
container.Add(this);
InitializeComponent();
}
/// <summary>
/// Installs the mouse hook for this application.
/// </summary>
public void InstallHook()
{
if (this._hMouseHook == IntPtr.Zero)
{
this._mouseProc = new MouseHook.MouseMessageEventHandler(MouseProc);
IntPtr hinstDLL = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
this._hMouseHook = UnsafeNativeMethods.SetWindowsHookEx(UnsafeNativeMethods.WH_MOUSE_LL, this._mouseProc, hinstDLL, 0);
if (this._hMouseHook == IntPtr.Zero)
{
//Failed to hook. Throw a HookException
int eCode = Marshal.GetLastWin32Error();
this._mouseProc = null;
throw new WindowsHookException(new Win32Exception(eCode).Message);
}
else
{
this.OnStateChanged(new WindowsHookLib.StateChangedEventArgs(this.State));
}
}
}
/// <summary>
/// Removes the mouse hook for this application.
/// </summary>
public void RemoveHook()
{
if (this._hMouseHook != IntPtr.Zero)
{
if (!UnsafeNativeMethods.UnhookWindowsHookEx(this._hMouseHook))
{
//Failed to remove the hook. Throw a HookException
int eCode = Marshal.GetLastWin32Error();
this._hMouseHook = IntPtr.Zero;
throw new WindowsHookException(new System.ComponentModel.Win32Exception(eCode).Message);
}
else
{
this._mouseProc = null;
this._hMouseHook = IntPtr.Zero;
this._hwnd = IntPtr.Zero;
this._cHandle = IntPtr.Zero;
this._button = MouseButtons.None;
this._buttonsDown = MouseButtons.None;
this._clicks = 0;
this.OnStateChanged(new WindowsHookLib.StateChangedEventArgs(this.State));
}
}
}
/// <summary>
/// Safely removes the hook without throwing exception.
/// </summary>
private void SafeRemove()
{
if (this._hMouseHook != IntPtr.Zero)
{
UnsafeNativeMethods.UnhookWindowsHookEx(this._hMouseHook);
this._mouseProc = null;
this._hMouseHook = IntPtr.Zero;
this._hwnd = IntPtr.Zero;
this._cHandle = IntPtr.Zero;
this._button = MouseButtons.None;
this._buttonsDown = MouseButtons.None;
this._clicks = 0;
this.OnStateChanged(new WindowsHookLib.StateChangedEventArgs(this.State));
}
}
//This sub processes all the mouse messages and passes to the other windows
private IntPtr MouseProc(Int32 nCode, IntPtr wParam, ref UnsafeNativeMethods.MouseInfo lParam)
{
if (nCode >= UnsafeNativeMethods.HC_ACTION)
{
this._cHandle = UnsafeNativeMethods.WindowFromPoint(lParam.pt);
int m = wParam.ToInt32();
WindowsHookLib.MouseEventArgs e = null;
if (m == UnsafeNativeMethods.WM_MOUSEMOVE)
{
e = new WindowsHookLib.MouseEventArgs(this._buttonsDown, 0, lParam.pt, 0);
this.OnMouseMove(e);
}
else if (m == UnsafeNativeMethods.WM_LBUTTONDOWN)
{
e = this.GetMouseDownArgs(lParam, MouseButtons.Left);
this.OnMouseDown(e);
}
else if (m == UnsafeNativeMethods.WM_RBUTTONDOWN)
{
e = this.GetMouseDownArgs(lParam, MouseButtons.Right);
this.OnMouseDown(e);
}
else if (m == UnsafeNativeMethods.WM_MBUTTONDOWN)
{
e = this.GetMouseDownArgs(lParam, MouseButtons.Middle);
this.OnMouseDown(e);
}
else if (m == UnsafeNativeMethods.WM_XBUTTONDOWN | m == UnsafeNativeMethods.WM_NCXBUTTONDOWN)
{
int hiWord = (Int16)(lParam.mouseData >> 16);
if (hiWord == 1)
{
e = this.GetMouseDownArgs(lParam, MouseButtons.XButton1);
this.OnMouseDown(e);
}
else if (hiWord == 2)
{
e = this.GetMouseDownArgs(lParam, MouseButtons.XButton2);
this.OnMouseDown(e);
}
}
else if (m == UnsafeNativeMethods.WM_LBUTTONUP)
{
this.OnMouseClick(lParam, MouseButtons.Left);
e = this.GetMouseUpArgs(lParam, MouseButtons.Left);
this.OnMouseUp(e);
}
else if (m == UnsafeNativeMethods.WM_RBUTTONUP)
{
this.OnMouseClick(lParam, MouseButtons.Right);
e = this.GetMouseUpArgs(lParam, MouseButtons.Right);
this.OnMouseUp(e);
}
else if (m == UnsafeNativeMethods.WM_MBUTTONUP)
{
this.OnMouseClick(lParam, MouseButtons.Middle);
e = this.GetMouseUpArgs(lParam, MouseButtons.Middle);
this.OnMouseUp(e);
}
else if (m == UnsafeNativeMethods.WM_XBUTTONUP | m == UnsafeNativeMethods.WM_NCXBUTTONUP)
{
int hiWord = (Int16)(lParam.mouseData >> 16);
if (hiWord == 1)
{
this.OnMouseClick(lParam, MouseButtons.XButton1);
e = this.GetMouseUpArgs(lParam, MouseButtons.XButton1);
this.OnMouseUp(e);
}
else if (hiWord == 2)
{
this.OnMouseClick(lParam, MouseButtons.XButton2);
e = this.GetMouseUpArgs(lParam, MouseButtons.XButton2);
this.OnMouseUp(e);
}
}
else if (m == UnsafeNativeMethods.WM_MOUSEWHEEL | m == UnsafeNativeMethods.WM_MOUSEHWHEEL)
{
int hiWord = (Int16)(lParam.mouseData >> 16);
e = new WindowsHookLib.MouseEventArgs(MouseButtons.None, 0, lParam.pt, hiWord);
this.OnMouseWheel(e);
}
if (e != null && e.Handled)
return new IntPtr(1);
}
return UnsafeNativeMethods.CallNextHookEx(this._hMouseHook, nCode, wParam, ref lParam);
}
/// <summary>
/// Sets the mouse down data for the MouseEventArgs object
/// and calls OnMouseDown method to raise the mouse down event.
/// </summary>
/// <param name="lParam">A MouseData structure object
/// that contains the data for the mouse down event.</param>
/// <param name="btn">A mouse button that is down.</param>
private WindowsHookLib.MouseEventArgs GetMouseDownArgs(UnsafeNativeMethods.MouseInfo lParam, MouseButtons btn)
{
WindowsHookLib.MouseEventArgs e;
if (this._clicks == 1 && this._button == btn && this._hwnd == this._cHandle && (lParam.time - this_time) <= SystemInformation.DoubleClickTime && this._rectangle.Contains(lParam.pt.X, lParam.pt.Y))
{
this._clicks = 2;
e = new WindowsHookLib.MouseEventArgs(btn, this._clicks, lParam.pt, 0);
}
else
{
this._clicks = 1;
e = new WindowsHookLib.MouseEventArgs(btn, this._clicks, lParam.pt, 0);
}
this._button = btn;
this._buttonsDown = this._buttonsDown | btn;
this_time = lParam.time;
this._hwnd = this._cHandle;
this._rectangle.Location = new Point((int)(lParam.pt.X - (this._rectangle.Width / 2)), (int)(lParam.pt.Y - (this._rectangle.Height / 2)));
return e;
}
/// <summary>
/// Sets the mouse up data for the MouseEventArgs object
/// and calls OnMouseUp method to raise the mouse up event.
/// </summary>
/// <param name="lParam">A MouseData structure object
/// that contains the data for the mouse up event.</param>
/// <param name="btn">A mouse button that is up.</param>
private WindowsHookLib.MouseEventArgs GetMouseUpArgs(UnsafeNativeMethods.MouseInfo lParam, MouseButtons btn)
{
this._buttonsDown = (this._buttonsDown & ~btn);
this._button = btn;
return new WindowsHookLib.MouseEventArgs(btn, 1, lParam.pt, 0);
}
/// <summary>
/// Checks the mouse up data and calls OnMouseclick or OnMouseDoubleClick events.
/// </summary>
/// <param name="lParam">A MouseData structure object
/// that contains the data for the mouse up event.</param>
/// <param name="btn">A mouse button that is up.</param>
private void OnMouseClick(UnsafeNativeMethods.MouseInfo lParam, MouseButtons btn)
{
if (this._button == btn && this._hwnd == this._cHandle && this._clicks == 1)
this.OnMouseClick(new System.Windows.Forms.MouseEventArgs(btn, 1, lParam.pt.X, lParam.pt.Y, 0));
else if (this._button == btn && this._hwnd == this._cHandle && this._clicks == 2)
{
this.OnMouseDoubleClick(new System.Windows.Forms.MouseEventArgs(btn, 2, lParam.pt.X, lParam.pt.Y, 0));
this._clicks = 0;
}
}
#region ' Synthesize Event '
/// <summary>
/// Synthesizes a mouse down event system wide.
/// </summary>
/// <param name="button">A Windows.Forms.MouseButton that should be down.</param>
public static void SynthesizeMouseDown(MouseButtons button)
{
MouseHook.SynthesizeMouseDown(button, IntPtr.Zero);
}
/// <summary>
/// Synthesizes a mouse down event system wide.
/// </summary>
/// <param name="button">A Windows.Forms.MouseButton that should be down.</param>
/// <param name="extraInfo">Specifies an additional value
/// associated with the mouse event.</param>
public static void SynthesizeMouseDown(MouseButtons button, IntPtr extraInfo)
{
UnsafeNativeMethods.MsInput input = new UnsafeNativeMethods.MsInput();
input.dwType = UnsafeNativeMethods.INPUT_MOUSE;
input.xi.dwExtraInfo = extraInfo;
if (button == MouseButtons.Left)
input.xi.dwFlags = UnsafeNativeMethods.MOUSEEVENTF_LEFTDOWN;
else if (button == MouseButtons.Right)
input.xi.dwFlags = UnsafeNativeMethods.MOUSEEVENTF_RIGHTDOWN;
else if (button == MouseButtons.Middle)
input.xi.dwFlags = UnsafeNativeMethods.MOUSEEVENTF_MIDDLEDOWN;
else if (button == MouseButtons.XButton1)
{
input.xi.dwFlags = UnsafeNativeMethods.MOUSEEVENTF_XDOWN;
input.xi.mouseData = UnsafeNativeMethods.XBUTTON1;
}
else if (button == MouseButtons.XButton2)
{
input.xi.dwFlags = UnsafeNativeMethods.MOUSEEVENTF_XDOWN;
input.xi.mouseData = UnsafeNativeMethods.XBUTTON2;
}
if (UnsafeNativeMethods.SendInput(1, ref input, Marshal.SizeOf(input)) == 0)
{
//Failed to synthesize the mouse event. Throw a HookException
int eCode = Marshal.GetLastWin32Error();
throw new WindowsHookException(new Win32Exception(eCode).Message);
}
}
/// <summary>
/// Synthesizes a mouse up event system wide.
/// </summary>
/// <param name="button">A Windows.Forms.MouseButton that should be up.</param>
public static void SynthesizeMouseUp(MouseButtons button)
{
MouseHook.SynthesizeMouseUp(button, IntPtr.Zero);
}
/// <summary>
/// Synthesizes a mouse up event system wide.
/// </summary>
/// <param name="button">A Windows.Forms.MouseButton that should be up.</param>
/// <param name="extraInfo">Specifies an additional value
/// associated with the mouse event.</param>
public static void SynthesizeMouseUp(MouseButtons button, IntPtr extraInfo)
{
UnsafeNativeMethods.MsInput input = new UnsafeNativeMethods.MsInput();
input.dwType = UnsafeNativeMethods.INPUT_MOUSE;
input.xi.dwExtraInfo = extraInfo;
if (button == MouseButtons.Left)
input.xi.dwFlags = UnsafeNativeMethods.MOUSEEVENTF_LEFTUP;
else if (button == MouseButtons.Right)
input.xi.dwFlags = UnsafeNativeMethods.MOUSEEVENTF_RIGHTUP;
else if (button == MouseButtons.Middle)
input.xi.dwFlags = UnsafeNativeMethods.MOUSEEVENTF_MIDDLEUP;
else if (button == MouseButtons.XButton1)
{
input.xi.dwFlags = UnsafeNativeMethods.MOUSEEVENTF_XUP;
input.xi.mouseData = UnsafeNativeMethods.XBUTTON1;
}
else if (button == MouseButtons.XButton2)
{
input.xi.dwFlags = UnsafeNativeMethods.MOUSEEVENTF_XUP;
input.xi.mouseData = UnsafeNativeMethods.XBUTTON2;
}
if (UnsafeNativeMethods.SendInput(1, ref input, Marshal.SizeOf(input)) == 0)
{
//Failed to synthesize the mouse event. Throw a HookException
int eCode = Marshal.GetLastWin32Error();
throw new WindowsHookException(new Win32Exception(eCode).Message);
}
}
/// <summary>
/// Synthesizes a mouse wheel event system wide.
/// </summary>
/// <param name="wheelClicks">A positive value indicates that the wheel was rotated forward,
/// away from the user; a negative value indicates that the wheel was rotated backward, toward
/// the user. One wheel click is defined as wheel delta, which is 120.</param>
public static void SynthesizeMouseWheel(int wheelClicks)
{
MouseHook.SynthesizeMouseWheel(wheelClicks, IntPtr.Zero);
}
/// <summary>
/// Synthesizes a mouse wheel event system wide.
/// </summary>
/// <param name="wheelClicks">A positive value indicates that the wheel was rotated forward,
/// away from the user; a negative value indicates that the wheel was rotated backward, toward
/// the user. One wheel click is defined as wheel delta, which is 120.</param>
/// <param name="extraInfo">Specifies an additional value
/// associated with the mouse event.</param>
public static void SynthesizeMouseWheel(int wheelClicks, IntPtr extraInfo)
{
UnsafeNativeMethods.MsInput input = new UnsafeNativeMethods.MsInput();
input.dwType = UnsafeNativeMethods.INPUT_MOUSE;
input.xi.dwExtraInfo = extraInfo;
input.xi.dwFlags = UnsafeNativeMethods.MOUSEEVENTF_WHEEL;
input.xi.mouseData = (UInt32)(UnsafeNativeMethods.WHEEL_DELTA * wheelClicks);
if (UnsafeNativeMethods.SendInput(1, ref input, Marshal.SizeOf(input)) == 0)
{
//Failed to synthesize the mouse event. Throw a HookException
int eCode = Marshal.GetLastWin32Error();
throw new WindowsHookException(new Win32Exception(eCode).Message);
}
}
/// <summary>
/// Synthesizes a mouse move event system wide.
/// </summary>
/// <param name="location">A screen location where the mouse should be moved.</param>
/// <param name="mapping">Specifies where the mouse coordinates should be mapped.</param>
public static void SynthesizeMouseMove(Point location, MapOn mapping)
{
MouseHook.SynthesizeMouseMove(location, mapping, IntPtr.Zero);
}
/// <summary>
/// Synthesizes a mouse move event system wide.
/// </summary>
/// <param name="location">A screen location where the mouse should be moved.</param>
/// <param name="mapping">Specifies where the mouse coordinates should be mapped.</param>
/// <param name="extraInfo">Specifies an additional value
/// associated with the mouse event.</param>
public static void SynthesizeMouseMove(Point location, MapOn mapping, IntPtr extraInfo)
{
UnsafeNativeMethods.MsInput input = new UnsafeNativeMethods.MsInput();
input.dwType = UnsafeNativeMethods.INPUT_MOUSE;
if (mapping == MapOn.Relative)
{
input.xi.pt = location;
}
else if (mapping == MapOn.PrimaryMonitor)
{
input.xi.pt.X = (int)Math.Ceiling((double)(Math.Ceiling((double)(location.X * 65535)) / SystemInformation.PrimaryMonitorSize.Width)) + 1;
input.xi.pt.Y = (int)Math.Ceiling((double)(Math.Ceiling((double)(location.Y * 65535)) / SystemInformation.PrimaryMonitorSize.Height)) + 1;
}
else if (mapping == MapOn.VirtualDesktop)
{
input.xi.pt.X = (int)Math.Ceiling((double)(Math.Ceiling((double)(location.X * 65535)) / SystemInformation.VirtualScreen.Width)) + 1;
input.xi.pt.Y = (int)Math.Ceiling((double)(Math.Ceiling((double)(location.Y * 65535)) / SystemInformation.VirtualScreen.Height)) + 1;
}
input.xi.dwExtraInfo = extraInfo;
input.xi.dwFlags = (UnsafeNativeMethods.MOUSEEVENTF_MOVE | (UInt32)mapping);
if (UnsafeNativeMethods.SendInput(1, ref input, Marshal.SizeOf(input)) == 0)
{
//Failed to synthesize the mouse event. Throw a HookException
int eCode = Marshal.GetLastWin32Error();
throw new WindowsHookException(new Win32Exception(eCode).Message);
}
}
#endregion
#endregion
#region ' On Event '
/// <summary>
/// Raises the WindowsHookLib.MouseHook.StateChanged event.
/// </summary>
/// <param name="e">A WindowsHookLib.StateChangedEventArgs
/// that contains the event data.</param>
protected virtual void OnStateChanged(WindowsHookLib.StateChangedEventArgs e)
{
if (StateChanged != null)
StateChanged(this, e);
}
/// <summary>
/// Raises the WindowsHookLib.MouseHook.MouseMove event.
/// </summary>
/// <param name="e">A WindowsHookLib.MouseEventArgs
/// that contains the event data.</param>
protected virtual void OnMouseMove(WindowsHookLib.MouseEventArgs e)
{
if (MouseMove != null)
MouseMove(this._cHandle, e);
}
/// <summary>
/// Raises the WindowsHookLib.MouseHook.MouseDown event.
/// </summary>
/// <param name="e">A WindowsHookLib.MouseEventArgs
/// that contains the event data.</param>
protected virtual void OnMouseDown(WindowsHookLib.MouseEventArgs e)
{
if (MouseDown != null)
MouseDown(this._cHandle, e);
}
/// <summary>
/// Raises the WindowsHookLib.MouseHook.MouseUp event.
/// </summary>
/// <param name="e">A WindowsHookLib.MouseEventArgs
/// that contains the event data.</param>
protected virtual void OnMouseUp(WindowsHookLib.MouseEventArgs e)
{
if (MouseUp != null)
MouseUp(this._cHandle, e);
}
/// <summary>
/// Raises the WindowsHookLib.MouseHook.MouseClick event.
/// </summary>
/// <param name="e">A System.Windows.Forms.MouseEventArgs
/// that contains the event data.</param>
protected virtual void OnMouseClick(System.Windows.Forms.MouseEventArgs e)
{
if (MouseClick != null)
MouseClick(this._cHandle, e);
}
/// <summary>
/// Raises the WindowsHookLib.MouseHook.MouseDoubleClick event.
/// </summary>
/// <param name="e">A System.Windows.Forms.MouseEventArgs
/// that contains the event data.</param>
protected virtual void OnMouseDoubleClick(System.Windows.Forms.MouseEventArgs e)
{
if (MouseDoubleClick != null)
MouseDoubleClick(this._cHandle, e);
}
/// <summary>
/// Raises the WindowsHookLib.MouseHook.MouseWheel event.
/// </summary>
/// <param name="e">A WindowsHookLib.MouseEventArgs
/// that contains the event data.</param>
protected virtual void OnMouseWheel(WindowsHookLib.MouseEventArgs e)
{
if (MouseWheel != null)
MouseWheel(IntPtr.Zero, e);
}
#endregion
}
}