Advertisement
Guest User

Untitled

a guest
Aug 26th, 2012
576
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.97 KB | None | 0 0
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using Microsoft.Xna.Framework;
  4. using Microsoft.Xna.Framework.Input;
  5.  
  6. //http://www.gamedev.net/topic/457783-xna-getting-text-from-keyboard/
  7. namespace Ruminate.GUI {
  8.  
  9.     public class CharacterEventArgs : EventArgs {
  10.  
  11.         private readonly char character;
  12.         private readonly int lParam;
  13.  
  14.         public CharacterEventArgs(char character, int lParam) {
  15.             this.character = character;
  16.             this.lParam = lParam;
  17.         }
  18.  
  19.         public char Character { get { return character; } }
  20.         public int Param { get { return lParam; } }
  21.         public int RepeatCount { get { return lParam & 0xffff; } }
  22.         public bool ExtendedKey { get { return (lParam & (1 << 24)) > 0; } }
  23.         public bool AltPressed { get { return (lParam & (1 << 29)) > 0; } }
  24.         public bool PreviousState { get { return (lParam & (1 << 30)) > 0; } }
  25.         public bool TransitionState { get { return (lParam & (1 << 31)) > 0; } }
  26.  
  27.     }
  28.  
  29.     public class KeyEventArgs : EventArgs {
  30.  
  31.         private Keys keyCode;
  32.  
  33.         public KeyEventArgs(Keys keyCode) {
  34.             this.keyCode = keyCode;
  35.         }
  36.  
  37.         public Keys KeyCode { get { return keyCode; } }
  38.     }
  39.  
  40.     public class MouseEventArgs : EventArgs {
  41.         private MouseButton button;
  42.         private int clicks;
  43.         private int x;
  44.         private int y;
  45.         private int delta;
  46.  
  47.         public MouseButton Button { get { return button; } }
  48.         public int Clicks { get { return clicks; } }
  49.         public int X { get { return x; } }
  50.         public int Y { get { return y; } }
  51.         public Point Location { get { return new Point(x, y); } }
  52.         public int Delta { get { return delta; } }
  53.  
  54.         public MouseEventArgs(MouseButton button, int clicks, int x, int y, int delta) {
  55.             this.button = button;
  56.             this.clicks = clicks;
  57.             this.x = x;
  58.             this.y = y;
  59.             this.delta = delta;
  60.         }
  61.  
  62.     }
  63.  
  64.     public delegate void CharEnteredHandler(object sender, CharacterEventArgs e);
  65.     public delegate void KeyEventHandler(object sender, KeyEventArgs e);
  66.     public delegate void MouseEventHandler(object sender, MouseEventArgs e);
  67.  
  68.     /// <summary>   /// Mouse Key Flags from WinUser.h for mouse related WM messages.</summary>
  69.     [Flags]
  70.     public enum MouseKeys {
  71.         LButton = 0x01,
  72.         RButton = 0x02,
  73.         Shift = 0x04,
  74.         Control = 0x08,
  75.         MButton = 0x10,
  76.         XButton1 = 0x20,
  77.         XButton2 = 0x40
  78.     }
  79.     public enum MouseButton {
  80.         None,
  81.         Left,
  82.         Right,
  83.         Middle,
  84.         X1,
  85.         X2
  86.     }
  87.  
  88.     public static class InputSystem {
  89.  
  90.         #region Events
  91.  
  92.         /// <summary>Event raised when a character has been entered.</summary>     
  93.         public static event CharEnteredHandler CharEntered;
  94.  
  95.         /// <summary>Event raised when a key has been pressed down. May fire multiple times due to keyboard repeat.</summary>      
  96.         public static event KeyEventHandler KeyDown;
  97.  
  98.         /// <summary>Event raised when a key has been released.</summary>
  99.         public static event KeyEventHandler KeyUp;
  100.  
  101.         /// <summary>Event raised when a mouse button is pressed.</summary>
  102.         public static event MouseEventHandler MouseDown;
  103.  
  104.         /// <summary>Event raised when a mouse button is released.</summary>   
  105.         public static event MouseEventHandler MouseUp;
  106.  
  107.         /// <summary>Event raised when the mouse changes location.</summary>
  108.         public static event MouseEventHandler MouseMove;
  109.  
  110.         /// <summary>Event raised when the mouse has hovered in the same location for a short period of time.</summary>    
  111.         public static event MouseEventHandler MouseHover;
  112.  
  113.         /// <summary>Event raised when the mouse wheel has been moved.</summary>   
  114.         public static event MouseEventHandler MouseWheel;
  115.  
  116.         /// <summary>Event raised when a mouse button has been double clicked.</summary>   
  117.         public static event MouseEventHandler MouseDoubleClick;
  118.  
  119.         #endregion
  120.  
  121.         delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
  122.         public static bool Initialized { get; private set; }
  123.         static IntPtr prevWndProc;
  124.         static WndProc hookProcDelegate;
  125.         static IntPtr hIMC;
  126.  
  127.         #region Win32 Constants
  128.         const int GWL_WNDPROC = -4;
  129.         const int WM_KEYDOWN = 0x100;
  130.         const int WM_KEYUP = 0x101;
  131.         const int WM_CHAR = 0x102;
  132.         const int WM_IME_SETCONTEXT = 0x281;
  133.         const int WM_INPUTLANGCHANGE = 0x51;
  134.         const int WM_GETDLGCODE = 0x87;
  135.         const int WM_IME_COMPOSITION = 0x10F;
  136.         const int DLGC_WANTALLKEYS = 4;
  137.         const int WM_MOUSEMOVE = 0x200;
  138.         const int WM_LBUTTONDOWN = 0x201;
  139.         const int WM_LBUTTONUP = 0x202;
  140.         const int WM_LBUTTONDBLCLK = 0x203;
  141.         const int WM_RBUTTONDOWN = 0x204;
  142.         const int WM_RBUTTONUP = 0x205;
  143.         const int WM_RBUTTONDBLCLK = 0x206;
  144.         const int WM_MBUTTONDOWN = 0x207;
  145.         const int WM_MBUTTONUP = 0x208;
  146.         const int WM_MBUTTONDBLCLK = 0x209;
  147.         const int WM_MOUSEWHEEL = 0x20A;
  148.         const int WM_XBUTTONDOWN = 0x20B;
  149.         const int WM_XBUTTONUP = 0x20C;
  150.         const int WM_XBUTTONDBLCLK = 0x20D;
  151.         const int WM_MOUSEHOVER = 0x2A1;
  152.         #endregion
  153.  
  154.         #region DLL Imports
  155.         [DllImport("Imm32.dll")]
  156.         static extern IntPtr ImmGetContext(IntPtr hWnd);
  157.  
  158.         [DllImport("Imm32.dll")]
  159.         static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);
  160.  
  161.         [DllImport("user32.dll")]
  162.         static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
  163.  
  164.         [DllImport("user32.dll", CharSet = CharSet.Auto)]
  165.         static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
  166.         #endregion
  167.  
  168.         public static int MouseX {
  169.             get {
  170.                 return Mouse.GetState().X;
  171.             }
  172.         }
  173.  
  174.         public static int MouseY {
  175.             get {
  176.                 return Mouse.GetState().Y;
  177.             }
  178.         }
  179.  
  180.         public static Point MouseLocation {
  181.             get {
  182.                 MouseState state = Mouse.GetState();
  183.                 return new Point(state.X, state.Y);
  184.             }
  185.         }
  186.  
  187.         public static bool ShiftDown {
  188.             get {
  189.                 KeyboardState state = Keyboard.GetState();
  190.                 return state.IsKeyDown(Keys.LeftShift) || state.IsKeyDown(Keys.RightShift);
  191.             }
  192.         }
  193.  
  194.         public static bool CtrlDown {
  195.             get {
  196.                 KeyboardState state = Keyboard.GetState();
  197.                 return state.IsKeyDown(Keys.LeftControl) || state.IsKeyDown(Keys.RightControl);
  198.             }
  199.         }
  200.  
  201.         public static bool AltDown {
  202.             get {
  203.                 KeyboardState state = Keyboard.GetState();
  204.                 return state.IsKeyDown(Keys.LeftAlt) || state.IsKeyDown(Keys.RightAlt);
  205.             }
  206.         }
  207.  
  208.         /// <summary>Initialize the TextInput with the given GameWindow.</summary> 
  209.         /// <param name="window">The XNA window to which text input should be linked.</param>  
  210.         public static void Initialize(GameWindow window) {
  211.             if (Initialized) { return; }
  212.  
  213.             hookProcDelegate = HookProc;
  214.             prevWndProc = (IntPtr)SetWindowLong(window.Handle, GWL_WNDPROC, (int)Marshal.GetFunctionPointerForDelegate(hookProcDelegate));
  215.             hIMC = ImmGetContext(window.Handle);
  216.  
  217.             Initialized = true;
  218.         }
  219.  
  220.         static IntPtr HookProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) {
  221.             IntPtr returnCode = CallWindowProc(prevWndProc, hWnd, msg, wParam, lParam);
  222.  
  223.             switch (msg) {
  224.                 case WM_GETDLGCODE:
  225.                     returnCode = (IntPtr)(returnCode.ToInt32() | DLGC_WANTALLKEYS);
  226.                     break;
  227.                 case WM_KEYDOWN:
  228.                     if (KeyDown != null)
  229.                         KeyDown(null, new KeyEventArgs((Keys)wParam));
  230.                     break;
  231.                 case WM_KEYUP:
  232.                     if (KeyUp != null)
  233.                         KeyUp(null, new KeyEventArgs((Keys)wParam));
  234.                     break;
  235.                 case WM_CHAR:
  236.                     if (CharEntered != null)
  237.                         CharEntered(null, new CharacterEventArgs((char)wParam, lParam.ToInt32()));
  238.                     break;
  239.                 case WM_IME_SETCONTEXT:
  240.                     if (wParam.ToInt32() == 1)
  241.                         ImmAssociateContext(hWnd, hIMC);
  242.                     break;
  243.                 case WM_INPUTLANGCHANGE:
  244.                     ImmAssociateContext(hWnd, hIMC);
  245.                     returnCode = (IntPtr)1;
  246.                     break;
  247.  
  248.                 // Mouse messages          
  249.                 case WM_MOUSEMOVE:
  250.                     if (MouseMove != null) {
  251.                         short x, y;
  252.                         MouseLocationFromLParam(lParam.ToInt32(), out x, out y);
  253.                         MouseMove(null, new MouseEventArgs(MouseButton.None, 0, x, y, 0));
  254.                     }
  255.                     break;
  256.                 case WM_MOUSEHOVER:
  257.                     if (MouseHover != null) {
  258.                         short x, y;
  259.                         MouseLocationFromLParam(lParam.ToInt32(), out x, out y);
  260.                         MouseHover(null, new MouseEventArgs(MouseButton.None, 0, x, y, 0));
  261.                     }
  262.                     break;
  263.                 case WM_MOUSEWHEEL:
  264.                     if (MouseWheel != null) {
  265.                         short x, y;
  266.                         MouseLocationFromLParam(lParam.ToInt32(), out x, out y);
  267.                         MouseWheel(null, new MouseEventArgs(MouseButton.None, 0, x, y, (wParam.ToInt32() >> 16) / 120));
  268.                     }
  269.                     break;
  270.                 case WM_LBUTTONDOWN:
  271.                     RaiseMouseDownEvent(MouseButton.Left, wParam.ToInt32(), lParam.ToInt32());
  272.                     break;
  273.                 case WM_LBUTTONUP:
  274.                     RaiseMouseUpEvent(MouseButton.Left, wParam.ToInt32(), lParam.ToInt32());
  275.                     break;
  276.                 case WM_LBUTTONDBLCLK:
  277.                     RaiseMouseDblClickEvent(MouseButton.Left, wParam.ToInt32(), lParam.ToInt32());
  278.                     break;
  279.                 case WM_RBUTTONDOWN:
  280.                     RaiseMouseDownEvent(MouseButton.Right, wParam.ToInt32(), lParam.ToInt32());
  281.                     break;
  282.                 case WM_RBUTTONUP:
  283.                     RaiseMouseUpEvent(MouseButton.Right, wParam.ToInt32(), lParam.ToInt32());
  284.                     break;
  285.                 case WM_RBUTTONDBLCLK:
  286.                     RaiseMouseDblClickEvent(MouseButton.Right, wParam.ToInt32(), lParam.ToInt32());
  287.                     break;
  288.                 case WM_MBUTTONDOWN:
  289.                     RaiseMouseDownEvent(MouseButton.Middle, wParam.ToInt32(), lParam.ToInt32());
  290.                     break;
  291.                 case WM_MBUTTONUP:
  292.                     RaiseMouseUpEvent(MouseButton.Middle, wParam.ToInt32(), lParam.ToInt32());
  293.                     break;
  294.                 case WM_MBUTTONDBLCLK:
  295.                     RaiseMouseDblClickEvent(MouseButton.Middle, wParam.ToInt32(), lParam.ToInt32());
  296.                     break;
  297.                 case WM_XBUTTONDOWN:
  298.                     if ((wParam.ToInt32() & 0x10000) != 0) {
  299.                         RaiseMouseDownEvent(MouseButton.X1, wParam.ToInt32(), lParam.ToInt32());
  300.                     } else if ((wParam.ToInt32() & 0x20000) != 0) {
  301.                         RaiseMouseDownEvent(MouseButton.X2, wParam.ToInt32(), lParam.ToInt32());
  302.                     }
  303.                     break;
  304.                 case WM_XBUTTONUP:
  305.                     if ((wParam.ToInt32() & 0x10000) != 0) {
  306.                         RaiseMouseUpEvent(MouseButton.X1, wParam.ToInt32(), lParam.ToInt32());
  307.                     } else if ((wParam.ToInt32() & 0x20000) != 0) {
  308.                         RaiseMouseUpEvent(MouseButton.X2, wParam.ToInt32(), lParam.ToInt32());
  309.                     }
  310.                     break;
  311.                 case WM_XBUTTONDBLCLK:
  312.                     if ((wParam.ToInt32() & 0x10000) != 0) {
  313.                         RaiseMouseDblClickEvent(MouseButton.X1, wParam.ToInt32(), lParam.ToInt32());
  314.                     } else if ((wParam.ToInt32() & 0x20000) != 0) {
  315.                         RaiseMouseDblClickEvent(MouseButton.X2, wParam.ToInt32(), lParam.ToInt32());
  316.                     }
  317.                     break;
  318.             }
  319.  
  320.             return returnCode;
  321.         }
  322.  
  323.         #region Mouse Message Helpers
  324.         static void RaiseMouseDownEvent(MouseButton button, int wParam, int lParam) {
  325.             if (MouseDown != null) {
  326.                 short x, y;
  327.                 MouseLocationFromLParam(lParam, out x, out y);
  328.                 MouseDown(null, new MouseEventArgs(button, 1, x, y, 0));
  329.             }
  330.         }
  331.  
  332.         static void RaiseMouseUpEvent(MouseButton button, int wParam, int lParam) {
  333.             if (MouseUp != null) {
  334.                 short x, y;
  335.                 MouseLocationFromLParam(lParam, out x, out y);
  336.                 MouseUp(null, new MouseEventArgs(button, 1, x, y, 0));
  337.             }
  338.         }
  339.  
  340.         static void RaiseMouseDblClickEvent(MouseButton button, int wParam, int lParam) {
  341.             if (MouseDoubleClick != null) {
  342.                 short x, y;
  343.                 MouseLocationFromLParam(lParam, out x, out y);
  344.                 MouseDoubleClick(null, new MouseEventArgs(button, 1, x, y, 0));
  345.             }
  346.         }
  347.  
  348.         static void MouseLocationFromLParam(int lParam, out short x, out short y) {
  349.             // Cast to signed shorts to get sign extension on negative coordinates (of course this would only be possible if mouse capture was enabled).   
  350.             x = (short)(lParam & 0xFFFF);
  351.             y = (short)(lParam >> 16);
  352.         }
  353.         #endregion
  354.     }
  355. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement