Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
InputManager.Windows.RawInput.Keyboard.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
4 
5 using System;
6 using System.Collections.Generic;
7 using System.Runtime.InteropServices;
8 using System.Windows.Forms;
9 using System.Windows.Interop;
10 
11 using SharpDX.Multimedia;
12 using SharpDX.RawInput;
13 
14 using WinFormsKeys = System.Windows.Forms.Keys;
15 
16 namespace SiliconStudio.Paradox.Input
17 {
18  public partial class InputManager
19  {
20  private static readonly Dictionary<WinFormsKeys, Keys> mapKeys = new Dictionary<WinFormsKeys, Keys>();
21 
22  private void BindRawInputKeyboard(Control winformControl)
23  {
24  EnsureMapKeys();
25 
26  if (winformControl.Handle == IntPtr.Zero)
27  {
28  winformControl.HandleCreated += (sender, args) =>
29  {
30  if (winformControl.Handle != IntPtr.Zero)
31  {
32  BindRawInputKeyboard(winformControl);
33  }
34  };
35  }
36  else
37  {
38  SharpDX.RawInput.Device.RegisterDevice(UsagePage.Generic, UsageId.GenericKeyboard, DeviceFlags.None, winformControl.Handle);
39  SharpDX.RawInput.Device.KeyboardInput += DeviceOnKeyboardInput;
40  }
41  }
42 
43  private void BindRawInputKeyboard(System.Windows.Window winformControl)
44  {
45  EnsureMapKeys();
46 
47  var interopHelper = new WindowInteropHelper(winformControl);
48  interopHelper.EnsureHandle();
49  SharpDX.RawInput.Device.RegisterDevice(UsagePage.Generic, UsageId.GenericKeyboard, DeviceFlags.None, interopHelper.Handle);
50  SharpDX.RawInput.Device.KeyboardInput += DeviceOnKeyboardInput;
51  }
52 
53  private void DeviceOnKeyboardInput(object sender, KeyboardInputEventArgs rawKb)
54  {
55  // Code partially from: http://molecularmusings.wordpress.com/2011/09/05/properly-handling-keyboard-input/
56  var key = Keys.None;
57 
58  var virtualKey = rawKb.Key;
59  var scanCode = rawKb.MakeCode;
60  var flags = rawKb.ScanCodeFlags;
61 
62  if ((int)virtualKey == 255)
63  {
64  // discard "fake keys" which are part of an escaped sequence
65  return;
66  }
67 
68  if (virtualKey == WinFormsKeys.ShiftKey)
69  {
70  // correct left-hand / right-hand SHIFT
71  virtualKey = (WinFormsKeys)MapVirtualKey(scanCode, MAPVK_VSC_TO_VK_EX);
72  }
73  else if (virtualKey == WinFormsKeys.NumLock)
74  {
75  // correct PAUSE/BREAK and NUM LOCK silliness, and set the extended bit
76  scanCode = MapVirtualKey((int)virtualKey, MAPVK_VK_TO_VSC) | 0x100;
77  }
78 
79  // e0 and e1 are escape sequences used for certain special keys, such as PRINT and PAUSE/BREAK.
80  // see http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
81  bool isE0 = ((flags & ScanCodeFlags.E0) != 0);
82  bool isE1 = ((flags & ScanCodeFlags.E1) != 0);
83 
84  if (isE1)
85  {
86  // for escaped sequences, turn the virtual key into the correct scan code using MapVirtualKey.
87  // however, MapVirtualKey is unable to map VK_PAUSE (this is a known bug), hence we map that by hand.
88  scanCode = virtualKey == WinFormsKeys.Pause ? 0x45 : MapVirtualKey((int)virtualKey, MAPVK_VK_TO_VSC);
89  }
90 
91  switch (virtualKey)
92  {
93  // right-hand CONTROL and ALT have their e0 bit set
94  case WinFormsKeys.ControlKey:
95  virtualKey = isE0 ? WinFormsKeys.RControlKey : WinFormsKeys.LControlKey;
96  break;
97 
98  case WinFormsKeys.Menu:
99  virtualKey = isE0 ? WinFormsKeys.RMenu : WinFormsKeys.LMenu;
100  break;
101 
102  // NUMPAD ENTER has its e0 bit set
103  case WinFormsKeys.Return:
104  if (isE0)
105  key = Keys.NumPadEnter;
106  break;
107  }
108 
109 
110  if (key == Keys.None)
111  {
112  mapKeys.TryGetValue(virtualKey, out key);
113  }
114 
115 
116  if (key != Keys.None)
117  {
118  bool isKeyUp = (flags & ScanCodeFlags.Break) != 0;
119 
120  if (isKeyUp)
121  {
122  lock (KeyboardInputEvents)
123  {
124  KeyboardInputEvents.Add(new KeyboardInputEvent { Key = key, Type = InputEventType.Up });
125  }
126  }
127  else
128  {
129  lock (KeyboardInputEvents)
130  {
131  KeyboardInputEvents.Add(new KeyboardInputEvent { Key = key, Type = InputEventType.Down });
132  }
133  }
134  }
135  }
136 
137  private static void AddKeys(WinFormsKeys fromKey, Keys toKey)
138  {
139  if (!mapKeys.ContainsKey(fromKey))
140  {
141  mapKeys.Add(fromKey, toKey);
142  }
143  }
144 
145  private static void EnsureMapKeys()
146  {
147  lock (mapKeys)
148  {
149  if (mapKeys.Count > 0)
150  {
151  return;
152  }
153  AddKeys(WinFormsKeys.None, Keys.None);
154  AddKeys(WinFormsKeys.Cancel, Keys.Cancel);
155  AddKeys(WinFormsKeys.Back, Keys.Back);
156  AddKeys(WinFormsKeys.Tab, Keys.Tab);
157  AddKeys(WinFormsKeys.LineFeed, Keys.LineFeed);
158  AddKeys(WinFormsKeys.Clear, Keys.Clear);
159  AddKeys(WinFormsKeys.Enter, Keys.Enter);
160  AddKeys(WinFormsKeys.Return, Keys.Return);
161  AddKeys(WinFormsKeys.Pause, Keys.Pause);
162  AddKeys(WinFormsKeys.Capital, Keys.Capital);
163  AddKeys(WinFormsKeys.CapsLock, Keys.CapsLock);
164  AddKeys(WinFormsKeys.HangulMode, Keys.HangulMode);
165  AddKeys(WinFormsKeys.KanaMode, Keys.KanaMode);
166  AddKeys(WinFormsKeys.JunjaMode, Keys.JunjaMode);
167  AddKeys(WinFormsKeys.FinalMode, Keys.FinalMode);
168  AddKeys(WinFormsKeys.HanjaMode, Keys.HanjaMode);
169  AddKeys(WinFormsKeys.KanjiMode, Keys.KanjiMode);
170  AddKeys(WinFormsKeys.Escape, Keys.Escape);
171  AddKeys(WinFormsKeys.IMEConvert, Keys.ImeConvert);
172  AddKeys(WinFormsKeys.IMENonconvert, Keys.ImeNonConvert);
173  AddKeys(WinFormsKeys.IMEAccept, Keys.ImeAccept);
174  AddKeys(WinFormsKeys.IMEModeChange, Keys.ImeModeChange);
175  AddKeys(WinFormsKeys.Space, Keys.Space);
176  AddKeys(WinFormsKeys.PageUp, Keys.PageUp);
177  AddKeys(WinFormsKeys.Prior, Keys.Prior);
178  AddKeys(WinFormsKeys.Next, Keys.Next);
179  AddKeys(WinFormsKeys.PageDown, Keys.PageDown);
180  AddKeys(WinFormsKeys.End, Keys.End);
181  AddKeys(WinFormsKeys.Home, Keys.Home);
182  AddKeys(WinFormsKeys.Left, Keys.Left);
183  AddKeys(WinFormsKeys.Up, Keys.Up);
184  AddKeys(WinFormsKeys.Right, Keys.Right);
185  AddKeys(WinFormsKeys.Down, Keys.Down);
186  AddKeys(WinFormsKeys.Select, Keys.Select);
187  AddKeys(WinFormsKeys.Print, Keys.Print);
188  AddKeys(WinFormsKeys.Execute, Keys.Execute);
189  AddKeys(WinFormsKeys.PrintScreen, Keys.PrintScreen);
190  AddKeys(WinFormsKeys.Snapshot, Keys.Snapshot);
191  AddKeys(WinFormsKeys.Insert, Keys.Insert);
192  AddKeys(WinFormsKeys.Delete, Keys.Delete);
193  AddKeys(WinFormsKeys.Help, Keys.Help);
194  AddKeys(WinFormsKeys.D0, Keys.D0);
195  AddKeys(WinFormsKeys.D1, Keys.D1);
196  AddKeys(WinFormsKeys.D2, Keys.D2);
197  AddKeys(WinFormsKeys.D3, Keys.D3);
198  AddKeys(WinFormsKeys.D4, Keys.D4);
199  AddKeys(WinFormsKeys.D5, Keys.D5);
200  AddKeys(WinFormsKeys.D6, Keys.D6);
201  AddKeys(WinFormsKeys.D7, Keys.D7);
202  AddKeys(WinFormsKeys.D8, Keys.D8);
203  AddKeys(WinFormsKeys.D9, Keys.D9);
204  AddKeys(WinFormsKeys.A, Keys.A);
205  AddKeys(WinFormsKeys.B, Keys.B);
206  AddKeys(WinFormsKeys.C, Keys.C);
207  AddKeys(WinFormsKeys.D, Keys.D);
208  AddKeys(WinFormsKeys.E, Keys.E);
209  AddKeys(WinFormsKeys.F, Keys.F);
210  AddKeys(WinFormsKeys.G, Keys.G);
211  AddKeys(WinFormsKeys.H, Keys.H);
212  AddKeys(WinFormsKeys.I, Keys.I);
213  AddKeys(WinFormsKeys.J, Keys.J);
214  AddKeys(WinFormsKeys.K, Keys.K);
215  AddKeys(WinFormsKeys.L, Keys.L);
216  AddKeys(WinFormsKeys.M, Keys.M);
217  AddKeys(WinFormsKeys.N, Keys.N);
218  AddKeys(WinFormsKeys.O, Keys.O);
219  AddKeys(WinFormsKeys.P, Keys.P);
220  AddKeys(WinFormsKeys.Q, Keys.Q);
221  AddKeys(WinFormsKeys.R, Keys.R);
222  AddKeys(WinFormsKeys.S, Keys.S);
223  AddKeys(WinFormsKeys.T, Keys.T);
224  AddKeys(WinFormsKeys.U, Keys.U);
225  AddKeys(WinFormsKeys.V, Keys.V);
226  AddKeys(WinFormsKeys.W, Keys.W);
227  AddKeys(WinFormsKeys.X, Keys.X);
228  AddKeys(WinFormsKeys.Y, Keys.Y);
229  AddKeys(WinFormsKeys.Z, Keys.Z);
230  AddKeys(WinFormsKeys.LWin, Keys.LeftWin);
231  AddKeys(WinFormsKeys.RWin, Keys.RightWin);
232  AddKeys(WinFormsKeys.Apps, Keys.Apps);
233  AddKeys(WinFormsKeys.Sleep, Keys.Sleep);
234  AddKeys(WinFormsKeys.NumPad0, Keys.NumPad0);
235  AddKeys(WinFormsKeys.NumPad1, Keys.NumPad1);
236  AddKeys(WinFormsKeys.NumPad2, Keys.NumPad2);
237  AddKeys(WinFormsKeys.NumPad3, Keys.NumPad3);
238  AddKeys(WinFormsKeys.NumPad4, Keys.NumPad4);
239  AddKeys(WinFormsKeys.NumPad5, Keys.NumPad5);
240  AddKeys(WinFormsKeys.NumPad6, Keys.NumPad6);
241  AddKeys(WinFormsKeys.NumPad7, Keys.NumPad7);
242  AddKeys(WinFormsKeys.NumPad8, Keys.NumPad8);
243  AddKeys(WinFormsKeys.NumPad9, Keys.NumPad9);
244  AddKeys(WinFormsKeys.Multiply, Keys.Multiply);
245  AddKeys(WinFormsKeys.Add, Keys.Add);
246  AddKeys(WinFormsKeys.Separator, Keys.Separator);
247  AddKeys(WinFormsKeys.Subtract, Keys.Subtract);
248  AddKeys(WinFormsKeys.Decimal, Keys.Decimal);
249  AddKeys(WinFormsKeys.Divide, Keys.Divide);
250  AddKeys(WinFormsKeys.F1, Keys.F1);
251  AddKeys(WinFormsKeys.F2, Keys.F2);
252  AddKeys(WinFormsKeys.F3, Keys.F3);
253  AddKeys(WinFormsKeys.F4, Keys.F4);
254  AddKeys(WinFormsKeys.F5, Keys.F5);
255  AddKeys(WinFormsKeys.F6, Keys.F6);
256  AddKeys(WinFormsKeys.F7, Keys.F7);
257  AddKeys(WinFormsKeys.F8, Keys.F8);
258  AddKeys(WinFormsKeys.F9, Keys.F9);
259  AddKeys(WinFormsKeys.F10, Keys.F10);
260  AddKeys(WinFormsKeys.F11, Keys.F11);
261  AddKeys(WinFormsKeys.F12, Keys.F12);
262  AddKeys(WinFormsKeys.F13, Keys.F13);
263  AddKeys(WinFormsKeys.F14, Keys.F14);
264  AddKeys(WinFormsKeys.F15, Keys.F15);
265  AddKeys(WinFormsKeys.F16, Keys.F16);
266  AddKeys(WinFormsKeys.F17, Keys.F17);
267  AddKeys(WinFormsKeys.F18, Keys.F18);
268  AddKeys(WinFormsKeys.F19, Keys.F19);
269  AddKeys(WinFormsKeys.F20, Keys.F20);
270  AddKeys(WinFormsKeys.F21, Keys.F21);
271  AddKeys(WinFormsKeys.F22, Keys.F22);
272  AddKeys(WinFormsKeys.F23, Keys.F23);
273  AddKeys(WinFormsKeys.F24, Keys.F24);
274  AddKeys(WinFormsKeys.NumLock, Keys.NumLock);
275  AddKeys(WinFormsKeys.Scroll, Keys.Scroll);
276  AddKeys(WinFormsKeys.LShiftKey, Keys.LeftShift);
277  AddKeys(WinFormsKeys.RShiftKey, Keys.RightShift);
278  AddKeys(WinFormsKeys.LControlKey, Keys.LeftCtrl);
279  AddKeys(WinFormsKeys.RControlKey, Keys.RightCtrl);
280  AddKeys(WinFormsKeys.LMenu, Keys.LeftAlt);
281  AddKeys(WinFormsKeys.RMenu, Keys.RightAlt);
282  AddKeys(WinFormsKeys.BrowserBack, Keys.BrowserBack);
283  AddKeys(WinFormsKeys.BrowserForward, Keys.BrowserForward);
284  AddKeys(WinFormsKeys.BrowserRefresh, Keys.BrowserRefresh);
285  AddKeys(WinFormsKeys.BrowserStop, Keys.BrowserStop);
286  AddKeys(WinFormsKeys.BrowserSearch, Keys.BrowserSearch);
287  AddKeys(WinFormsKeys.BrowserFavorites, Keys.BrowserFavorites);
288  AddKeys(WinFormsKeys.BrowserHome, Keys.BrowserHome);
289  AddKeys(WinFormsKeys.VolumeMute, Keys.VolumeMute);
290  AddKeys(WinFormsKeys.VolumeDown, Keys.VolumeDown);
291  AddKeys(WinFormsKeys.VolumeUp, Keys.VolumeUp);
292  AddKeys(WinFormsKeys.MediaNextTrack, Keys.MediaNextTrack);
293  AddKeys(WinFormsKeys.MediaPreviousTrack, Keys.MediaPreviousTrack);
294  AddKeys(WinFormsKeys.MediaStop, Keys.MediaStop);
295  AddKeys(WinFormsKeys.MediaPlayPause, Keys.MediaPlayPause);
296  AddKeys(WinFormsKeys.LaunchMail, Keys.LaunchMail);
297  AddKeys(WinFormsKeys.SelectMedia, Keys.SelectMedia);
298  AddKeys(WinFormsKeys.LaunchApplication1, Keys.LaunchApplication1);
299  AddKeys(WinFormsKeys.LaunchApplication2, Keys.LaunchApplication2);
300  AddKeys(WinFormsKeys.Oem1, Keys.Oem1);
301  AddKeys(WinFormsKeys.OemSemicolon, Keys.OemSemicolon);
302  AddKeys(WinFormsKeys.Oemplus, Keys.OemPlus);
303  AddKeys(WinFormsKeys.Oemcomma, Keys.OemComma);
304  AddKeys(WinFormsKeys.OemMinus, Keys.OemMinus);
305  AddKeys(WinFormsKeys.OemPeriod, Keys.OemPeriod);
306  AddKeys(WinFormsKeys.Oem2, Keys.Oem2);
307  AddKeys(WinFormsKeys.OemQuestion, Keys.OemQuestion);
308  AddKeys(WinFormsKeys.Oem3, Keys.Oem3);
309  AddKeys(WinFormsKeys.Oemtilde, Keys.OemTilde);
310  AddKeys(WinFormsKeys.Oem4, Keys.Oem4);
311  AddKeys(WinFormsKeys.OemOpenBrackets, Keys.OemOpenBrackets);
312  AddKeys(WinFormsKeys.Oem5, Keys.Oem5);
313  AddKeys(WinFormsKeys.OemPipe, Keys.OemPipe);
314  AddKeys(WinFormsKeys.Oem6, Keys.Oem6);
315  AddKeys(WinFormsKeys.OemCloseBrackets, Keys.OemCloseBrackets);
316  AddKeys(WinFormsKeys.Oem7, Keys.Oem7);
317  AddKeys(WinFormsKeys.OemQuotes, Keys.OemQuotes);
318  AddKeys(WinFormsKeys.Oem8, Keys.Oem8);
319  AddKeys(WinFormsKeys.Oem102, Keys.Oem102);
320  AddKeys(WinFormsKeys.OemBackslash, Keys.OemBackslash);
321  AddKeys(WinFormsKeys.Attn, Keys.Attn);
322  AddKeys(WinFormsKeys.Crsel, Keys.CrSel);
323  AddKeys(WinFormsKeys.Exsel, Keys.ExSel);
324  AddKeys(WinFormsKeys.EraseEof, Keys.EraseEof);
325  AddKeys(WinFormsKeys.Play, Keys.Play);
326  AddKeys(WinFormsKeys.Zoom, Keys.Zoom);
327  AddKeys(WinFormsKeys.NoName, Keys.NoName);
328  AddKeys(WinFormsKeys.Pa1, Keys.Pa1);
329  AddKeys(WinFormsKeys.OemClear, Keys.OemClear);
330  }
331  }
332 
333  const uint MAPVK_VK_TO_VSC = 0x00;
334  const uint MAPVK_VSC_TO_VK = 0x01;
335  const uint MAPVK_VK_TO_CHAR = 0x02;
336  const uint MAPVK_VSC_TO_VK_EX = 0x03;
337  const uint MAPVK_VK_TO_VSC_EX = 0x04;
338 
339  [DllImport("user32.dll")]
340  private static extern int MapVirtualKey(int uCode, uint uMapType);
341  }
342 }
343 #endif
Keys
Enumeration for keys.
Definition: Keys.cs:8
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ DXGI_FORMAT _In_ DWORD flags
Definition: DirectXTexP.h:170
SiliconStudio.Paradox.Input.Keys Keys
The type of the serialized type will be passed as a generic arguments of the serializer. Example: serializer of A becomes instantiated as Serializer{A}.