Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

há 8 meses
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // This code is distributed under MIT license.
  2. // Copyright (c) 2015 George Mamaladze
  3. // See license.txt or https://mit-license.org/
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Windows.Forms;
  8. using Gma.System.MouseKeyHook.WinApi;
  9. namespace Gma.System.MouseKeyHook.Implementation
  10. {
  11. /// <summary>
  12. /// Contains a snapshot of a keyboard state at certain moment and provides methods
  13. /// of querying whether specific keys are pressed or locked.
  14. /// </summary>
  15. /// <remarks>
  16. /// This class is basically a managed wrapper of GetKeyboardState API function
  17. /// http://msdn.microsoft.com/en-us/library/ms646299
  18. /// </remarks>
  19. public class KeyboardState
  20. {
  21. private readonly byte[] m_KeyboardStateNative;
  22. private KeyboardState(byte[] keyboardStateNative)
  23. {
  24. m_KeyboardStateNative = keyboardStateNative;
  25. }
  26. /// <summary>
  27. /// Makes a snapshot of a keyboard state to the moment of call and returns an
  28. /// instance of <see cref="KeyboardState" /> class.
  29. /// </summary>
  30. /// <returns>An instance of <see cref="KeyboardState" /> class representing a snapshot of keyboard state at certain moment.</returns>
  31. public static KeyboardState GetCurrent()
  32. {
  33. var keyboardStateNative = new byte[256];
  34. KeyboardNativeMethods.GetKeyboardState(keyboardStateNative);
  35. return new KeyboardState(keyboardStateNative);
  36. }
  37. internal byte[] GetNativeState()
  38. {
  39. return m_KeyboardStateNative;
  40. }
  41. /// <summary>
  42. /// Indicates whether specified key was down at the moment when snapshot was created or not.
  43. /// </summary>
  44. /// <param name="key">Key (corresponds to the virtual code of the key)</param>
  45. /// <returns><b>true</b> if key was down, <b>false</b> - if key was up.</returns>
  46. public bool IsDown(Keys key)
  47. {
  48. if ((int)key < 256) return IsDownRaw(key);
  49. if (key == Keys.Alt) return IsDownRaw(Keys.LMenu) || IsDownRaw(Keys.RMenu);
  50. if (key == Keys.Shift) return IsDownRaw(Keys.LShiftKey) || IsDownRaw(Keys.RShiftKey);
  51. if (key == Keys.Control) return IsDownRaw(Keys.LControlKey) || IsDownRaw(Keys.RControlKey);
  52. return false;
  53. }
  54. private bool IsDownRaw(Keys key)
  55. {
  56. var keyState = GetKeyState(key);
  57. var isDown = GetHighBit(keyState);
  58. return isDown;
  59. }
  60. /// <summary>
  61. /// Indicate weather specified key was toggled at the moment when snapshot was created or not.
  62. /// </summary>
  63. /// <param name="key">Key (corresponds to the virtual code of the key)</param>
  64. /// <returns>
  65. /// <b>true</b> if toggle key like (CapsLock, NumLocke, etc.) was on. <b>false</b> if it was off.
  66. /// Ordinal (non toggle) keys return always false.
  67. /// </returns>
  68. public bool IsToggled(Keys key)
  69. {
  70. var keyState = GetKeyState(key);
  71. var isToggled = GetLowBit(keyState);
  72. return isToggled;
  73. }
  74. /// <summary>
  75. /// Indicates weather every of specified keys were down at the moment when snapshot was created.
  76. /// The method returns false if even one of them was up.
  77. /// </summary>
  78. /// <param name="keys">Keys to verify whether they were down or not.</param>
  79. /// <returns><b>true</b> - all were down. <b>false</b> - at least one was up.</returns>
  80. public bool AreAllDown(IEnumerable<Keys> keys)
  81. {
  82. return keys.All(IsDown);
  83. }
  84. private byte GetKeyState(Keys key)
  85. {
  86. var virtualKeyCode = (int) key;
  87. if (virtualKeyCode < 0 || virtualKeyCode > 255)
  88. throw new ArgumentOutOfRangeException("key", key, "The value must be between 0 and 255.");
  89. return m_KeyboardStateNative[virtualKeyCode];
  90. }
  91. private static bool GetHighBit(byte value)
  92. {
  93. return value >> 7 != 0;
  94. }
  95. private static bool GetLowBit(byte value)
  96. {
  97. return (value & 1) != 0;
  98. }
  99. }
  100. }