Advertisement
Guest User

Untitled

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