/// <summary>Filters out a message before it is dispatched</summary> /// <param name="message"> /// Message that will be dispatched. You must not modify this message. /// </param> /// <returns> /// True if the message has been processed by the filter and should not be /// dispatched or false to continue processing of the message. /// </returns> bool IMessageFilter.PreFilterMessage(ref Message message) { // Process the message differently based on its message id switch (message.Msg) { // Key on the keyboard was pressed / released case (int)UnsafeNativeMethods.WindowMessages.WM_KEYDOWN: { int virtualKeyCode = message.WParam.ToInt32(); // bool repetition = (message.LParam.ToInt32() & WM_KEYDOWN_WASDOWN) != 0; OnKeyPressed((Keys)virtualKeyCode); if (virtualKeyCode == 17) { ctrlKeyDown = true; } if (virtualKeyCode == 18) { altKeyDown = true; } UnsafeNativeMethods.TranslateMessage(ref message); return(true); // consumed! } case (int)UnsafeNativeMethods.WindowMessages.WM_KEYUP: { int virtualKeyCode = message.WParam.ToInt32(); OnKeyReleased((Keys)virtualKeyCode); // Workaround for strange behavior of ctrl and alt key combinations // Pressing & releasing both generates two keydowns but only one keyup. if (virtualKeyCode == 17) { ctrlKeyDown = false; if (altKeyDown) { OnKeyReleased((Keys)18); altKeyDown = false; } } else if (virtualKeyCode == 18) { altKeyDown = false; if (ctrlKeyDown) { OnKeyReleased((Keys)17); ctrlKeyDown = false; } } return(true); // consumed! } // Character has been entered on the keyboard case (int)UnsafeNativeMethods.WindowMessages.WM_CHAR: { char character = (char)message.WParam.ToInt32(); OnCharacterEntered(character); return(true); // consumed! } // Mouse has been moved case (int)UnsafeNativeMethods.WindowMessages.WM_MOUSEMOVE: { if (!this.trackingMouse) { int result = UnsafeNativeMethods.TrackMouseEvent(ref this.mouseEventTrackData); Debug.Assert( result != 0, "Could not set up registration for mouse events", "The TrackMouseEvent() function failed, which means the game will not " + "detect when the mouse leaves the game window. This might result in " + "the assumed mouse position remaining somewhere near the window border " + "even though the mouse has been moved away from the game window." ); this.trackingMouse = (result != 0); } short x = (short)(message.LParam.ToInt32() & 0xFFFF); short y = (short)(message.LParam.ToInt32() >> 16); OnMouseMoved((float)x, (float)y); break; } // Left mouse button pressed / released case (int)UnsafeNativeMethods.WindowMessages.WM_LBUTTONDOWN: case (int)UnsafeNativeMethods.WindowMessages.WM_LBUTTONDBLCLK: { OnMouseButtonPressed(MouseButtons.Left); break; } case (int)UnsafeNativeMethods.WindowMessages.WM_LBUTTONUP: { OnMouseButtonReleased(MouseButtons.Left); break; } // Right mouse button pressed / released case (int)UnsafeNativeMethods.WindowMessages.WM_RBUTTONDOWN: case (int)UnsafeNativeMethods.WindowMessages.WM_RBUTTONDBLCLK: { OnMouseButtonPressed(MouseButtons.Right); break; } case (int)UnsafeNativeMethods.WindowMessages.WM_RBUTTONUP: { OnMouseButtonReleased(MouseButtons.Right); break; } // Middle mouse button pressed / released case (int)UnsafeNativeMethods.WindowMessages.WM_MBUTTONDOWN: case (int)UnsafeNativeMethods.WindowMessages.WM_MBUTTONDBLCLK: { OnMouseButtonPressed(MouseButtons.Middle); break; } case (int)UnsafeNativeMethods.WindowMessages.WM_MBUTTONUP: { OnMouseButtonReleased(MouseButtons.Middle); break; } // Extended mouse button pressed / released case (int)UnsafeNativeMethods.WindowMessages.WM_XBUTTONDOWN: case (int)UnsafeNativeMethods.WindowMessages.WM_XBUTTONDBLCLK: { short button = (short)(message.WParam.ToInt32() >> 16); if (button == 1) { OnMouseButtonPressed(MouseButtons.X1); } if (button == 2) { OnMouseButtonPressed(MouseButtons.X2); } break; } case (int)UnsafeNativeMethods.WindowMessages.WM_XBUTTONUP: { short button = (short)(message.WParam.ToInt32() >> 16); if (button == 1) { OnMouseButtonReleased(MouseButtons.X1); } if (button == 2) { OnMouseButtonReleased(MouseButtons.X2); } break; } // Mouse wheel rotated case (int)UnsafeNativeMethods.WindowMessages.WM_MOUSEHWHEEL: { short ticks = (short)(message.WParam.ToInt32() >> 16); OnMouseWheelRotated((float)ticks / 120.0f); break; } // Mouse has left the window's client area case (int)UnsafeNativeMethods.WindowMessages.WM_MOUSELEAVE: { OnMouseMoved(-1.0f, -1.0f); this.trackingMouse = false; break; } } return(false); }
/// <summary>Filters out a message before it is dispatched</summary> /// <param name="message"> /// Message that will be dispatched. You must not modify this message. /// </param> /// <returns> /// True if the message has been processed by the filter and should not be /// dispatched or false to continue processing of the message. /// </returns> bool IMessageFilter.PreFilterMessage(ref Message message) { // Process the message differently based on its message id switch (message.Msg) { case (int)UnsafeNativeMethods.WindowMessages.WM_SYSKEYDOWN: { int virtualKeyCode = message.WParam.ToInt32(); // Don't handle these Alt+key presses because they'd block Windows' shortcuts bool dontHandle = (virtualKeyCode == (int)Keys.F4) || (virtualKeyCode == (int)Keys.Escape) || (virtualKeyCode == (int)Keys.Space); if (dontHandle) { break; } goto case (int)UnsafeNativeMethods.WindowMessages.WM_KEYDOWN; } // Key on the keyboard was pressed case (int)UnsafeNativeMethods.WindowMessages.WM_KEYDOWN: { int virtualKeyCode = message.WParam.ToInt32(); switch (virtualKeyCode) { #if false // XNA doesn't want to distinguish Return and Enter case 0x0D: { // VK_ENTER bool extended = (message.LParam.ToInt32() & 0x01000000) != 0; if (extended) { OnKeyPressed(Keys.Enter); } else { OnKeyPressed(Keys.??); } break; } #endif case 0x10: { // VK_SHIFT OnKeyPressed( (Keys)UnsafeNativeMethods.MapVirtualKey( (uint)(message.LParam.ToInt32() & 0x00FF0000) >> 16, (uint)UnsafeNativeMethods.MapType.ScanCodeToVirtualKeyEx ) ); break; } case 0x11: { // VK_CONTROL bool extended = (message.LParam.ToInt32() & 0x01000000) != 0; if (extended) { OnKeyPressed(Keys.RightControl); } else { OnKeyPressed(Keys.LeftControl); } break; } case 0x12: { // VK_MENU bool extended = (message.LParam.ToInt32() & 0x01000000) != 0; if (extended) { OnKeyPressed(Keys.RightAlt); } else { OnKeyPressed(Keys.LeftAlt); } break; } default: { OnKeyPressed((Keys)virtualKeyCode); break; } } UnsafeNativeMethods.TranslateMessage(ref message); return(true); // consumed! } // Key on the keyboard was released case (int)UnsafeNativeMethods.WindowMessages.WM_SYSKEYUP: case (int)UnsafeNativeMethods.WindowMessages.WM_KEYUP: { int virtualKeyCode = message.WParam.ToInt32(); switch (virtualKeyCode) { #if false // We could, but XNA doesn't want to distinguish Return and Enter case 0x0D: { // VK_ENTER bool extended = (message.LParam.ToInt32() & 0x01000000) != 0; if (extended) { OnKeyReleased(Keys.Enter); } else { OnKeyReleased(Keys.??); } break; } #endif case 0x10: { // VK_SHIFT OnKeyReleased( (Keys)UnsafeNativeMethods.MapVirtualKey( (uint)(message.LParam.ToInt32() & 0x00FF0000) >> 16, (uint)UnsafeNativeMethods.MapType.ScanCodeToVirtualKeyEx ) ); break; } case 0x11: { // VK_CONTROL bool isExtendedKey = (message.LParam.ToInt32() & (1 << 24)) != 0; if (isExtendedKey) { OnKeyReleased(Keys.RightControl); } else { OnKeyReleased(Keys.LeftControl); } break; } case 0x12: { // VK_MENU bool isExtendedKey = (message.LParam.ToInt32() & (1 << 24)) != 0; if (isExtendedKey) { OnKeyReleased(Keys.RightAlt); } else { OnKeyReleased(Keys.LeftAlt); } break; } default: { OnKeyReleased((Keys)virtualKeyCode); break; } } return(true); // consumed! } // Character has been entered on the keyboard case (int)UnsafeNativeMethods.WindowMessages.WM_CHAR: { char character = (char)message.WParam.ToInt32(); OnCharacterEntered(character); return(true); // consumed! } // Mouse has been moved case (int)UnsafeNativeMethods.WindowMessages.WM_MOUSEMOVE: { if (!this.trackingMouse) { int result = UnsafeNativeMethods.TrackMouseEvent(ref this.mouseEventTrackData); Debug.Assert( result != 0, "Could not set up registration for mouse events", "The TrackMouseEvent() function failed, which means the game will not " + "detect when the mouse leaves the game window. This might result in " + "the assumed mouse position remaining somewhere near the window border " + "even though the mouse has been moved away from the game window." ); this.trackingMouse = (result != 0); } short x = (short)(message.LParam.ToInt32() & 0xFFFF); short y = (short)(message.LParam.ToInt32() >> 16); OnMouseMoved((float)x, (float)y); break; } // Left mouse button pressed / released case (int)UnsafeNativeMethods.WindowMessages.WM_LBUTTONDOWN: case (int)UnsafeNativeMethods.WindowMessages.WM_LBUTTONDBLCLK: { OnMouseButtonPressed(MouseButtons.Left); break; } case (int)UnsafeNativeMethods.WindowMessages.WM_LBUTTONUP: { OnMouseButtonReleased(MouseButtons.Left); break; } // Right mouse button pressed / released case (int)UnsafeNativeMethods.WindowMessages.WM_RBUTTONDOWN: case (int)UnsafeNativeMethods.WindowMessages.WM_RBUTTONDBLCLK: { OnMouseButtonPressed(MouseButtons.Right); break; } case (int)UnsafeNativeMethods.WindowMessages.WM_RBUTTONUP: { OnMouseButtonReleased(MouseButtons.Right); break; } // Middle mouse button pressed / released case (int)UnsafeNativeMethods.WindowMessages.WM_MBUTTONDOWN: case (int)UnsafeNativeMethods.WindowMessages.WM_MBUTTONDBLCLK: { OnMouseButtonPressed(MouseButtons.Middle); break; } case (int)UnsafeNativeMethods.WindowMessages.WM_MBUTTONUP: { OnMouseButtonReleased(MouseButtons.Middle); break; } // Extended mouse button pressed / released case (int)UnsafeNativeMethods.WindowMessages.WM_XBUTTONDOWN: case (int)UnsafeNativeMethods.WindowMessages.WM_XBUTTONDBLCLK: { short button = (short)(message.WParam.ToInt32() >> 16); if (button == 1) { OnMouseButtonPressed(MouseButtons.X1); } if (button == 2) { OnMouseButtonPressed(MouseButtons.X2); } break; } case (int)UnsafeNativeMethods.WindowMessages.WM_XBUTTONUP: { short button = (short)(message.WParam.ToInt32() >> 16); if (button == 1) { OnMouseButtonReleased(MouseButtons.X1); } if (button == 2) { OnMouseButtonReleased(MouseButtons.X2); } break; } // Mouse wheel rotated case (int)UnsafeNativeMethods.WindowMessages.WM_MOUSEHWHEEL: { short ticks = (short)(message.WParam.ToInt32() >> 16); OnMouseWheelRotated((float)ticks / 120.0f); break; } // Mouse has left the window's client area case (int)UnsafeNativeMethods.WindowMessages.WM_MOUSELEAVE: { OnMouseMoved(-1.0f, -1.0f); this.trackingMouse = false; break; } } return(false); }