/// <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) { return(CallNextHookEx(mouseHookHandle, nCode, wParam, lParam)); } //Marshall the data from callback. var info = (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct)); ushort subCode; switch (wParam) { case WM_LBUTTONDOWN: MouseState.AddPressedElement(MouseKeyCode.LeftButton); break; case WM_LBUTTONUP: MouseState.RemovePressedElement(MouseKeyCode.LeftButton, PressHold); break; case WM_RBUTTONDOWN: MouseState.AddPressedElement(MouseKeyCode.RightButton); break; case WM_RBUTTONUP: MouseState.RemovePressedElement(MouseKeyCode.RightButton, PressHold); break; case WM_MBUTTONDOWN: MouseState.AddPressedElement(MouseKeyCode.MiddleButton); break; case WM_MBUTTONUP: MouseState.RemovePressedElement(MouseKeyCode.MiddleButton, PressHold); break; case WM_MOUSEWHEEL: subCode = HiWord(info.MouseData); if (subCode == 120) { MouseState.AddScrollDirection(MouseScrollKeyCode.ScrollUp); } if (subCode == 65416) { MouseState.AddScrollDirection(MouseScrollKeyCode.ScrollDown); } break; case WM_MOUSEHWHEEL: subCode = HiWord(info.MouseData); if (subCode == 120) { MouseState.AddScrollDirection(MouseScrollKeyCode.ScrollRight); } if (subCode == 65416) { MouseState.AddScrollDirection(MouseScrollKeyCode.ScrollLeft); } break; case WM_XBUTTONDOWN: subCode = HiWord(info.MouseData); if (subCode == XBUTTON1) { MouseState.AddPressedElement(MouseKeyCode.X1Button); } if (subCode == XBUTTON2) { MouseState.AddPressedElement(MouseKeyCode.X2Button); } break; case WM_XBUTTONUP: subCode = HiWord(info.MouseData); if (subCode == XBUTTON1) { MouseState.RemovePressedElement(MouseKeyCode.X1Button, PressHold); } if (subCode == XBUTTON2) { MouseState.RemovePressedElement(MouseKeyCode.X2Button, PressHold); } break; case WM_MOUSEMOVE: MouseState.RegisterLocation(new System.Drawing.Point(info.Point.X, info.Point.Y), info.Time); break; } if (trapEnabled && TrapMouse) { return(1); } return(CallNextHookEx(mouseHookHandle, nCode, wParam, lParam)); }