/// <summary> /// A callback function which will be called every time a mouse activity detected /// </summary> /// <param name="nCode"> /// [in] Specifies whether the hook procedure must process the message. /// If nCode is HC_ACTION, the hook procedure must process the message. /// If nCode is less than zero, the hook procedure must pass the message to the /// CallNextHookEx function without further processing and must return the /// value returned by CallNextHookEx. /// </param> /// <param name="wParam"> /// [in] Specifies whether the message was sent by the current thread. /// If the message was sent by the current thread, it is nonzero; otherwise, it is zero. /// </param> /// <param name="lParam"> /// [in] Pointer to a CWPSTRUCT structure that contains details about the message. /// </param> /// <returns> /// If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx. /// If nCode is greater than or equal to zero, it is highly recommended that you call CallNextHookEx /// and return the value it returns; otherwise, other applications that have installed WH_CALLWNDPROC /// hooks will not receive hook notifications and may behave incorrectly as a result. If the hook /// procedure does not call CallNextHookEx, the return value should be zero. /// </returns> private static int MouseHookProc(int nCode, int wParam, IntPtr lParam) { if (nCode >= 0) { // marshall the data from callback MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct)); MouseButtons buttonClicked = MouseButtons.None; bool mouseDown = false; bool mouseUp = false; switch (wParam) { case WM_LBUTTONDOWN: mouseDown = true; buttonClicked = MouseButtons.Left; break; case WM_LBUTTONUP: mouseUp = true; buttonClicked = MouseButtons.Left; break; case WM_RBUTTONDOWN: mouseDown = true; buttonClicked = MouseButtons.Right; break; case WM_RBUTTONUP: mouseUp = true; buttonClicked = MouseButtons.Right; break; } // generate event MouseEventExtArgs e = new MouseEventExtArgs(buttonClicked, 1, mouseHookStruct.Point.X, mouseHookStruct.Point.Y, 0); #region Invoke Subscribed Events if (_mouseUpEvent != null && mouseUp) _mouseUpEvent.Invoke(null, e); if (_mouseDownEvent != null && mouseDown) _mouseDownEvent.Invoke(null, e); if (_mouseClickEvent != null && buttonClicked != MouseButtons.None) _mouseClickEvent.Invoke(null, e); if (_mouseMoveEvent != null && (_oldX != mouseHookStruct.Point.X || _oldY != mouseHookStruct.Point.Y)) { _oldX = mouseHookStruct.Point.X; _oldY = mouseHookStruct.Point.Y; if (_mouseMoveEvent != null) _mouseMoveEvent.Invoke(null, e); } #endregion // do not call the next hook if we've handle this event if (e.Handled) return -1; } // call next hook return CallNextHookEx(_mouseHookHandle, nCode, wParam, lParam); }