private IntPtr WindowProc(IntPtr handle, uint messageId, IntPtr wParam, IntPtr lParam) { try { switch (messageId) { case WinApi.WM_CLOSE: m_logic.CloseRequest(); return(IntPtr.Zero); case WinApi.WM_PAINT: Render(); return(IntPtr.Zero); case WinApi.WM_KEYDOWN: { var key = (Key)wParam.ToInt32(); if (m_keys[(int)key] == false) { m_keys[(int)key] = true; m_logic.InputEvent(new KeyboardKeyDownEventArgs(key)); } } return(IntPtr.Zero); case WinApi.WM_KEYUP: { var key = (Key)wParam.ToInt32(); m_keys[(int)key] = false; m_logic.InputEvent(new KeyboardKeyUpEventArgs(key)); } return(IntPtr.Zero); case WinApi.WM_KILLFOCUS: { for (int i = 0; i < m_keys.Length; i++) { if (m_keys[i]) { m_keys[i] = false; m_logic.InputEvent(new KeyboardKeyUpEventArgs((Key)i)); } } } return(IntPtr.Zero); case WinApi.WM_LBUTTONDOWN: OnMousedDown(MouseButton.Left, GetMousePosition(handle, lParam)); return(IntPtr.Zero); case WinApi.WM_LBUTTONUP: OnMouseUp(MouseButton.Left, GetMousePosition(handle, lParam)); return(IntPtr.Zero); case WinApi.WM_RBUTTONDOWN: OnMousedDown(MouseButton.Right, GetMousePosition(handle, lParam)); return(IntPtr.Zero); case WinApi.WM_RBUTTONUP: OnMouseUp(MouseButton.Right, GetMousePosition(handle, lParam)); return(IntPtr.Zero); case WinApi.WM_MBUTTONDOWN: OnMousedDown(MouseButton.Middle, GetMousePosition(handle, lParam)); return(IntPtr.Zero); case WinApi.WM_MBUTTONUP: OnMouseUp(MouseButton.Middle, GetMousePosition(handle, lParam)); return(IntPtr.Zero); case WinApi.WM_XBUTTONDOWN: { var button = ((wParam.ToInt32() >> 16) & 0xFFFF) == 1 ? MouseButton.Aux1 : MouseButton.Aux2; OnMousedDown(button, GetMousePosition(handle, lParam)); } return(IntPtr.Zero); case WinApi.WM_XBUTTONUP: { var button = ((wParam.ToInt32() >> 16) & 0xFFFF) == 1 ? MouseButton.Aux1 : MouseButton.Aux2; OnMouseUp(button, GetMousePosition(handle, lParam)); } return(IntPtr.Zero); case WinApi.WM_MOUSEMOVE: if (!m_isMouseInWindow) { m_isMouseInWindow = true; var cursor = WinApi.GetClassLong(handle, WinApi.GCL_HCURSOR); if (cursor == 0) { WinApi.SetCursor(IntPtr.Zero); } WinApi.TrackMouseEventParameters p = new WinApi.TrackMouseEventParameters(); p.cbSize = (uint)Marshal.SizeOf(typeof(WinApi.TrackMouseEventParameters)); p.dwFlags = WinApi.TME_LEAVE; p.hwndTrack = handle; WinApi.TrackMouseEvent(ref p); m_logic.InputEvent(new MouseEnterEventArgs()); } m_logic.InputEvent(new MouseMoveEventArgs(GetMousePosition(handle, lParam))); return(IntPtr.Zero); case WinApi.WM_MOUSELEAVE: m_isMouseInWindow = false; m_logic.InputEvent(new MouseLeaveEventArgs()); return(IntPtr.Zero); case WinApi.WM_MOUSEWHEEL: { var ticks = (short)((wParam.ToInt32() >> 16) & 0xFFFF); m_logic.InputEvent(new MouseWheelEventArgs(ticks / 120f, GetMousePosition(handle, lParam))); } return(IntPtr.Zero); case WinApi.WM_CHAR: { var c = (char)(wParam.ToInt32() & 0xFFFF); m_logic.InputEvent(new CharacterEventArgs(c)); } return(IntPtr.Zero); default: return(WinApi.DefWindowProc(handle, messageId, wParam, lParam)); } } catch (Exception ex) { Engine.LogError("Unhandled exception", ex); m_logic.UnhandledException(ex); return(WinApi.DefWindowProc(handle, messageId, wParam, lParam)); } }