1 //-------------------------------------------------------------------------------------- 2 // File: Keyboard.h 3 // 4 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 5 // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 6 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 7 // PARTICULAR PURPOSE. 8 // 9 // Copyright (c) Microsoft Corporation. All rights reserved. 10 // 11 // http://go.microsoft.com/fwlink/?LinkId=248929 12 //-------------------------------------------------------------------------------------- 13 14 #pragma once 15 16 // VS 2010/2012 do not support =default =delete 17 #ifndef DIRECTX_CTOR_DEFAULT 18 #if defined(_MSC_VER) && (_MSC_VER < 1800) 19 #define DIRECTX_CTOR_DEFAULT {} 20 #define DIRECTX_CTOR_DELETE ; 21 #else 22 #define DIRECTX_CTOR_DEFAULT =default; 23 #define DIRECTX_CTOR_DELETE =delete; 24 #endif 25 #endif 26 27 #pragma warning(push) 28 #pragma warning(disable : 4005) 29 #include <stdint.h> 30 #pragma warning(pop) 31 32 #include <memory> 33 34 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) 35 namespace ABI { namespace Windows { namespace UI { namespace Core { struct ICoreWindow; } } } } 36 #endif 37 38 39 namespace DirectX 40 { 41 class Keyboard 42 { 43 public: 44 Keyboard(); 45 Keyboard(Keyboard&& moveFrom); 46 Keyboard& operator= (Keyboard&& moveFrom); 47 virtual ~Keyboard(); 48 49 enum Keys 50 { 51 None = 0, 52 53 Back = 0x8, 54 Tab = 0x9, 55 56 Enter = 0xd, 57 58 Pause = 0x13, 59 CapsLock = 0x14, 60 Kana = 0x15, 61 62 Kanji = 0x19, 63 64 Escape = 0x1b, 65 ImeConvert = 0x1c, 66 ImeNoConvert = 0x1d, 67 68 Space = 0x20, 69 PageUp = 0x21, 70 PageDown = 0x22, 71 End = 0x23, 72 Home = 0x24, 73 Left = 0x25, 74 Up = 0x26, 75 Right = 0x27, 76 Down = 0x28, 77 Select = 0x29, 78 Print = 0x2a, 79 Execute = 0x2b, 80 PrintScreen = 0x2c, 81 Insert = 0x2d, 82 Delete = 0x2e, 83 Help = 0x2f, 84 D0 = 0x30, 85 D1 = 0x31, 86 D2 = 0x32, 87 D3 = 0x33, 88 D4 = 0x34, 89 D5 = 0x35, 90 D6 = 0x36, 91 D7 = 0x37, 92 D8 = 0x38, 93 D9 = 0x39, 94 95 A = 0x41, 96 B = 0x42, 97 C = 0x43, 98 D = 0x44, 99 E = 0x45, 100 F = 0x46, 101 G = 0x47, 102 H = 0x48, 103 I = 0x49, 104 J = 0x4a, 105 K = 0x4b, 106 L = 0x4c, 107 M = 0x4d, 108 N = 0x4e, 109 O = 0x4f, 110 P = 0x50, 111 Q = 0x51, 112 R = 0x52, 113 S = 0x53, 114 T = 0x54, 115 U = 0x55, 116 V = 0x56, 117 W = 0x57, 118 X = 0x58, 119 Y = 0x59, 120 Z = 0x5a, 121 LeftWindows = 0x5b, 122 RightWindows = 0x5c, 123 Apps = 0x5d, 124 125 Sleep = 0x5f, 126 NumPad0 = 0x60, 127 NumPad1 = 0x61, 128 NumPad2 = 0x62, 129 NumPad3 = 0x63, 130 NumPad4 = 0x64, 131 NumPad5 = 0x65, 132 NumPad6 = 0x66, 133 NumPad7 = 0x67, 134 NumPad8 = 0x68, 135 NumPad9 = 0x69, 136 Multiply = 0x6a, 137 Add = 0x6b, 138 Separator = 0x6c, 139 Subtract = 0x6d, 140 141 Decimal = 0x6e, 142 Divide = 0x6f, 143 F1 = 0x70, 144 F2 = 0x71, 145 F3 = 0x72, 146 F4 = 0x73, 147 F5 = 0x74, 148 F6 = 0x75, 149 F7 = 0x76, 150 F8 = 0x77, 151 F9 = 0x78, 152 F10 = 0x79, 153 F11 = 0x7a, 154 F12 = 0x7b, 155 F13 = 0x7c, 156 F14 = 0x7d, 157 F15 = 0x7e, 158 F16 = 0x7f, 159 F17 = 0x80, 160 F18 = 0x81, 161 F19 = 0x82, 162 F20 = 0x83, 163 F21 = 0x84, 164 F22 = 0x85, 165 F23 = 0x86, 166 F24 = 0x87, 167 168 NumLock = 0x90, 169 Scroll = 0x91, 170 171 LeftShift = 0xa0, 172 RightShift = 0xa1, 173 LeftControl = 0xa2, 174 RightControl = 0xa3, 175 LeftAlt = 0xa4, 176 RightAlt = 0xa5, 177 BrowserBack = 0xa6, 178 BrowserForward = 0xa7, 179 BrowserRefresh = 0xa8, 180 BrowserStop = 0xa9, 181 BrowserSearch = 0xaa, 182 BrowserFavorites = 0xab, 183 BrowserHome = 0xac, 184 VolumeMute = 0xad, 185 VolumeDown = 0xae, 186 VolumeUp = 0xaf, 187 MediaNextTrack = 0xb0, 188 MediaPreviousTrack = 0xb1, 189 MediaStop = 0xb2, 190 MediaPlayPause = 0xb3, 191 LaunchMail = 0xb4, 192 SelectMedia = 0xb5, 193 LaunchApplication1 = 0xb6, 194 LaunchApplication2 = 0xb7, 195 196 OemSemicolon = 0xba, 197 OemPlus = 0xbb, 198 OemComma = 0xbc, 199 OemMinus = 0xbd, 200 OemPeriod = 0xbe, 201 OemQuestion = 0xbf, 202 OemTilde = 0xc0, 203 204 OemOpenBrackets = 0xdb, 205 OemPipe = 0xdc, 206 OemCloseBrackets = 0xdd, 207 OemQuotes = 0xde, 208 Oem8 = 0xdf, 209 210 OemBackslash = 0xe2, 211 212 ProcessKey = 0xe5, 213 214 OemCopy = 0xf2, 215 OemAuto = 0xf3, 216 OemEnlW = 0xf4, 217 218 Attn = 0xf6, 219 Crsel = 0xf7, 220 Exsel = 0xf8, 221 EraseEof = 0xf9, 222 Play = 0xfa, 223 Zoom = 0xfb, 224 225 Pa1 = 0xfd, 226 OemClear = 0xfe, 227 }; 228 229 struct State 230 { 231 bool Reserved0 : 8; 232 bool Back : 1; // VK_BACK, 0x8 233 bool Tab : 1; // VK_TAB, 0x9 234 bool Reserved1 : 3; 235 bool Enter : 1; // VK_RETURN, 0xD 236 bool Reserved2 : 2; 237 bool Reserved3 : 3; 238 bool Pause : 1; // VK_PAUSE, 0x13 239 bool CapsLock : 1; // VK_CAPITAL, 0x14 240 bool Kana : 1; // VK_KANA, 0x15 241 bool Reserved4 : 2; 242 bool Reserved5 : 1; 243 bool Kanji : 1; // VK_KANJI, 0x19 244 bool Reserved6 : 1; 245 bool Escape : 1; // VK_ESCAPE, 0x1B 246 bool ImeConvert : 1; // VK_CONVERT, 0x1C 247 bool ImeNoConvert : 1; // VK_NONCONVERT, 0x1D 248 bool Reserved7 : 2; 249 bool Space : 1; // VK_SPACE, 0x20 250 bool PageUp : 1; // VK_PRIOR, 0x21 251 bool PageDown : 1; // VK_NEXT, 0x22 252 bool End : 1; // VK_END, 0x23 253 bool Home : 1; // VK_HOME, 0x24 254 bool Left : 1; // VK_LEFT, 0x25 255 bool Up : 1; // VK_UP, 0x26 256 bool Right : 1; // VK_RIGHT, 0x27 257 bool Down : 1; // VK_DOWN, 0x28 258 bool Select : 1; // VK_SELECT, 0x29 259 bool Print : 1; // VK_PRINT, 0x2A 260 bool Execute : 1; // VK_EXECUTE, 0x2B 261 bool PrintScreen : 1; // VK_SNAPSHOT, 0x2C 262 bool Insert : 1; // VK_INSERT, 0x2D 263 bool Delete : 1; // VK_DELETE, 0x2E 264 bool Help : 1; // VK_HELP, 0x2F 265 bool D0 : 1; // 0x30 266 bool D1 : 1; // 0x31 267 bool D2 : 1; // 0x32 268 bool D3 : 1; // 0x33 269 bool D4 : 1; // 0x34 270 bool D5 : 1; // 0x35 271 bool D6 : 1; // 0x36 272 bool D7 : 1; // 0x37 273 bool D8 : 1; // 0x38 274 bool D9 : 1; // 0x39 275 bool Reserved8 : 6; 276 bool Reserved9 : 1; 277 bool A : 1; // 0x41 278 bool B : 1; // 0x42 279 bool C : 1; // 0x43 280 bool D : 1; // 0x44 281 bool E : 1; // 0x45 282 bool F : 1; // 0x46 283 bool G : 1; // 0x47 284 bool H : 1; // 0x48 285 bool I : 1; // 0x49 286 bool J : 1; // 0x4A 287 bool K : 1; // 0x4B 288 bool L : 1; // 0x4C 289 bool M : 1; // 0x4D 290 bool N : 1; // 0x4E 291 bool O : 1; // 0x4F 292 bool P : 1; // 0x50 293 bool Q : 1; // 0x51 294 bool R : 1; // 0x52 295 bool S : 1; // 0x53 296 bool T : 1; // 0x54 297 bool U : 1; // 0x55 298 bool V : 1; // 0x56 299 bool W : 1; // 0x57 300 bool X : 1; // 0x58 301 bool Y : 1; // 0x59 302 bool Z : 1; // 0x5A 303 bool LeftWindows : 1; // VK_LWIN, 0x5B 304 bool RightWindows : 1; // VK_RWIN, 0x5C 305 bool Apps : 1; // VK_APPS, 0x5D 306 bool Reserved10 : 1; 307 bool Sleep : 1; // VK_SLEEP, 0x5F 308 bool NumPad0 : 1; // VK_NUMPAD0, 0x60 309 bool NumPad1 : 1; // VK_NUMPAD1, 0x61 310 bool NumPad2 : 1; // VK_NUMPAD2, 0x62 311 bool NumPad3 : 1; // VK_NUMPAD3, 0x63 312 bool NumPad4 : 1; // VK_NUMPAD4, 0x64 313 bool NumPad5 : 1; // VK_NUMPAD5, 0x65 314 bool NumPad6 : 1; // VK_NUMPAD6, 0x66 315 bool NumPad7 : 1; // VK_NUMPAD7, 0x67 316 bool NumPad8 : 1; // VK_NUMPAD8, 0x68 317 bool NumPad9 : 1; // VK_NUMPAD9, 0x69 318 bool Multiply : 1; // VK_MULTIPLY, 0x6A 319 bool Add : 1; // VK_ADD, 0x6B 320 bool Separator : 1; // VK_SEPARATOR, 0x6C 321 bool Subtract : 1; // VK_SUBTRACT, 0x6D 322 bool Decimal : 1; // VK_DECIMANL, 0x6E 323 bool Divide : 1; // VK_DIVIDE, 0x6F 324 bool F1 : 1; // VK_F1, 0x70 325 bool F2 : 1; // VK_F2, 0x71 326 bool F3 : 1; // VK_F3, 0x72 327 bool F4 : 1; // VK_F4, 0x73 328 bool F5 : 1; // VK_F5, 0x74 329 bool F6 : 1; // VK_F6, 0x75 330 bool F7 : 1; // VK_F7, 0x76 331 bool F8 : 1; // VK_F8, 0x77 332 bool F9 : 1; // VK_F9, 0x78 333 bool F10 : 1; // VK_F10, 0x79 334 bool F11 : 1; // VK_F11, 0x7A 335 bool F12 : 1; // VK_F12, 0x7B 336 bool F13 : 1; // VK_F13, 0x7C 337 bool F14 : 1; // VK_F14, 0x7D 338 bool F15 : 1; // VK_F15, 0x7E 339 bool F16 : 1; // VK_F16, 0x7F 340 bool F17 : 1; // VK_F17, 0x80 341 bool F18 : 1; // VK_F18, 0x81 342 bool F19 : 1; // VK_F19, 0x82 343 bool F20 : 1; // VK_F20, 0x83 344 bool F21 : 1; // VK_F21, 0x84 345 bool F22 : 1; // VK_F22, 0x85 346 bool F23 : 1; // VK_F23, 0x86 347 bool F24 : 1; // VK_F24, 0x87 348 bool Reserved11 : 8; 349 bool NumLock : 1; // VK_NUMLOCK, 0x90 350 bool Scroll : 1; // VK_SCROLL, 0x91 351 bool Reserved12 : 6; 352 bool Reserved13 : 8; 353 bool LeftShift : 1; // VK_LSHIFT, 0xA0 354 bool RightShift : 1; // VK_RSHIFT, 0xA1 355 bool LeftControl : 1; // VK_LCONTROL, 0xA2 356 bool RightControl : 1; // VK_RCONTROL, 0xA3 357 bool LeftAlt : 1; // VK_LMENU, 0xA4 358 bool RightAlt : 1; // VK_RMENU, 0xA5 359 bool BrowserBack : 1; // VK_BROWSER_BACK, 0xA6 360 bool BrowserForward : 1; // VK_BROWSER_FORWARD, 0xA7 361 bool BrowserRefresh : 1; // VK_BROWSER_REFRESH, 0xA8 362 bool BrowserStop : 1; // VK_BROWSER_STOP, 0xA9 363 bool BrowserSearch : 1; // VK_BROWSER_SEARCH, 0xAA 364 bool BrowserFavorites : 1; // VK_BROWSER_FAVORITES, 0xAB 365 bool BrowserHome : 1; // VK_BROWSER_HOME, 0xAC 366 bool VolumeMute : 1; // VK_VOLUME_MUTE, 0xAD 367 bool VolumeDown : 1; // VK_VOLUME_DOWN, 0xAE 368 bool VolumeUp : 1; // VK_VOLUME_UP, 0xAF 369 bool MediaNextTrack : 1; // VK_MEDIA_NEXT_TRACK, 0xB0 370 bool MediaPreviousTrack : 1;// VK_MEDIA_PREV_TRACK, 0xB1 371 bool MediaStop : 1; // VK_MEDIA_STOP, 0xB2 372 bool MediaPlayPause : 1; // VK_MEDIA_PLAY_PAUSE, 0xB3 373 bool LaunchMail : 1; // VK_LAUNCH_MAIL, 0xB4 374 bool SelectMedia : 1; // VK_LAUNCH_MEDIA_SELECT, 0xB5 375 bool LaunchApplication1 : 1;// VK_LAUNCH_APP1, 0xB6 376 bool LaunchApplication2 : 1;// VK_LAUNCH_APP2, 0xB7 377 bool Reserved14 : 2; 378 bool OemSemicolon : 1; // VK_OEM_1, 0xBA 379 bool OemPlus : 1; // VK_OEM_PLUS, 0xBB 380 bool OemComma : 1; // VK_OEM_COMMA, 0xBC 381 bool OemMinus : 1; // VK_OEM_MINUS, 0xBD 382 bool OemPeriod : 1; // VK_OEM_PERIOD, 0xBE 383 bool OemQuestion : 1; // VK_OEM_2, 0xBF 384 bool OemTilde : 1; // VK_OEM_3, 0xC0 385 bool Reserved15 : 7; 386 bool Reserved16 : 8; 387 bool Reserved17 : 8; 388 bool Reserved18 : 3; 389 bool OemOpenBrackets : 1; // VK_OEM_4, 0xDB 390 bool OemPipe : 1; // VK_OEM_5, 0xDC 391 bool OemCloseBrackets : 1; // VK_OEM_6, 0xDD 392 bool OemQuotes : 1; // VK_OEM_7, 0xDE 393 bool Oem8 : 1; // VK_OEM_8, 0xDF 394 bool Reserved19 : 2; 395 bool OemBackslash : 1; // VK_OEM_102, 0xE2 396 bool Reserved20 : 2; 397 bool ProcessKey : 1; // VK_PROCESSKEY, 0xE5 398 bool Reserved21 : 2; 399 bool Reserved22 : 8; 400 bool Reserved23 : 2; 401 bool OemCopy : 1; // 0XF2 402 bool OemAuto : 1; // 0xF3 403 bool OemEnlW : 1; // 0xF4 404 bool Reserved24 : 1; 405 bool Attn : 1; // VK_ATTN, 0xF6 406 bool Crsel : 1; // VK_CRSEL, 0xF7 407 bool Exsel : 1; // VK_EXSEL, 0xF8 408 bool EraseEof : 1; // VK_EREOF, 0xF9 409 bool Play : 1; // VK_PLAY, 0xFA 410 bool Zoom : 1; // VK_ZOOM, 0xFB 411 bool Reserved25 : 1; 412 bool Pa1 : 1; // VK_PA1, 0xFD 413 bool OemClear : 1; // VK_OEM_CLEAR, 0xFE 414 bool Reserved26: 1; 415 IsKeyDownState416 bool __cdecl IsKeyDown(Keys key) const 417 { 418 if (key >= 0 && key <= 0xff) 419 { 420 auto ptr = reinterpret_cast<const uint32_t*>(this); 421 unsigned int bf = 1u << (key & 0x1f); 422 return (ptr[(key >> 5)] & bf) != 0; 423 } 424 return false; 425 } 426 IsKeyUpState427 bool __cdecl IsKeyUp(Keys key) const 428 { 429 if (key >= 0 && key <= 0xfe) 430 { 431 auto ptr = reinterpret_cast<const uint32_t*>(this); 432 unsigned int bf = 1u << (key & 0x1f); 433 return (ptr[(key >> 5)] & bf) == 0; 434 } 435 return false; 436 } 437 }; 438 439 class KeyboardStateTracker 440 { 441 public: 442 State released; 443 State pressed; 444 KeyboardStateTracker()445 KeyboardStateTracker() { Reset(); } 446 447 void __cdecl Update(const State& state); 448 449 void __cdecl Reset(); 450 IsKeyPressed(Keys key)451 bool __cdecl IsKeyPressed(Keys key) const { return pressed.IsKeyDown(key); } IsKeyReleased(Keys key)452 bool __cdecl IsKeyReleased(Keys key) const { return released.IsKeyDown(key); } 453 454 public: 455 State lastState; 456 }; 457 458 // Retrieve the current state of the keyboard 459 State __cdecl GetState() const; 460 461 // Reset the keyboard state 462 void __cdecl Reset(); 463 464 #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) && defined(WM_USER) 465 static void __cdecl ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam); 466 #endif 467 468 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) 469 void __cdecl SetWindow(ABI::Windows::UI::Core::ICoreWindow* window); 470 #ifdef __cplusplus_winrt 471 void __cdecl SetWindow(Windows::UI::Core::CoreWindow^ window) 472 { 473 // See https://msdn.microsoft.com/en-us/library/hh755802.aspx 474 SetWindow(reinterpret_cast<ABI::Windows::UI::Core::ICoreWindow*>(window)); 475 } 476 #endif 477 #endif 478 479 // Singleton 480 static Keyboard& __cdecl Get(); 481 482 private: 483 // Private implementation. 484 class Impl; 485 486 std::unique_ptr<Impl> pImpl; 487 488 // Prevent copying. 489 Keyboard(Keyboard const&) DIRECTX_CTOR_DELETE 490 Keyboard& operator=(Keyboard const&) DIRECTX_CTOR_DELETE 491 }; 492 } 493