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.

KeyPressEventArgsExt.cs 4.0 KiB

há 8 meses
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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.Runtime.InteropServices;
  7. using System.Windows.Forms;
  8. using Gma.System.MouseKeyHook.Implementation;
  9. using Gma.System.MouseKeyHook.WinApi;
  10. namespace Gma.System.MouseKeyHook
  11. {
  12. /// <summary>
  13. /// Provides extended data for the <see cref='KeyListener.KeyPress' /> event.
  14. /// </summary>
  15. public class KeyPressEventArgsExt : KeyPressEventArgs
  16. {
  17. internal KeyPressEventArgsExt(char keyChar, int timestamp)
  18. : base(keyChar)
  19. {
  20. IsNonChar = keyChar == (char) 0x0;
  21. Timestamp = timestamp;
  22. }
  23. /// <summary>
  24. /// Initializes a new instance of the <see cref='KeyPressEventArgsExt' /> class.
  25. /// </summary>
  26. /// <param name="keyChar">
  27. /// Character corresponding to the key pressed. 0 char if represents a system or functional non char
  28. /// key.
  29. /// </param>
  30. public KeyPressEventArgsExt(char keyChar)
  31. : this(keyChar, Environment.TickCount)
  32. {
  33. }
  34. /// <summary>
  35. /// True if represents a system or functional non char key.
  36. /// </summary>
  37. public bool IsNonChar { get; }
  38. /// <summary>
  39. /// The system tick count of when the event occurred.
  40. /// </summary>
  41. public int Timestamp { get; }
  42. internal static IEnumerable<KeyPressEventArgsExt> FromRawDataApp(CallbackData data)
  43. {
  44. var wParam = data.WParam;
  45. var lParam = data.LParam;
  46. //http://msdn.microsoft.com/en-us/library/ms644984(v=VS.85).aspx
  47. const uint maskKeydown = 0x40000000; // for bit 30
  48. const uint maskKeyup = 0x80000000; // for bit 31
  49. const uint maskScanCode = 0xff0000; // for bit 23-16
  50. var flags = (uint) lParam.ToInt64();
  51. //bit 30 Specifies the previous key state. The value is 1 if the key is down before the message is sent; it is 0 if the key is up.
  52. var wasKeyDown = (flags & maskKeydown) > 0;
  53. //bit 31 Specifies the transition state. The value is 0 if the key is being pressed and 1 if it is being released.
  54. var isKeyReleased = (flags & maskKeyup) > 0;
  55. if (!wasKeyDown && !isKeyReleased)
  56. yield break;
  57. var virtualKeyCode = (int) wParam;
  58. var scanCode = checked((int) (flags & maskScanCode));
  59. const int fuState = 0;
  60. char[] chars;
  61. KeyboardNativeMethods.TryGetCharFromKeyboardState(virtualKeyCode, scanCode, fuState, out chars);
  62. if (chars == null) yield break;
  63. foreach (var ch in chars)
  64. yield return new KeyPressEventArgsExt(ch);
  65. }
  66. internal static IEnumerable<KeyPressEventArgsExt> FromRawDataGlobal(CallbackData data)
  67. {
  68. var wParam = data.WParam;
  69. var lParam = data.LParam;
  70. if ((int) wParam != Messages.WM_KEYDOWN && (int) wParam != Messages.WM_SYSKEYDOWN)
  71. yield break;
  72. var keyboardHookStruct =
  73. (KeyboardHookStruct) Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
  74. var virtualKeyCode = keyboardHookStruct.VirtualKeyCode;
  75. var scanCode = keyboardHookStruct.ScanCode;
  76. var fuState = keyboardHookStruct.Flags;
  77. if (virtualKeyCode == KeyboardNativeMethods.VK_PACKET)
  78. {
  79. var ch = (char) scanCode;
  80. yield return new KeyPressEventArgsExt(ch, keyboardHookStruct.Time);
  81. }
  82. else
  83. {
  84. char[] chars;
  85. KeyboardNativeMethods.TryGetCharFromKeyboardState(virtualKeyCode, scanCode, fuState, out chars);
  86. if (chars == null) yield break;
  87. foreach (var current in chars)
  88. yield return new KeyPressEventArgsExt(current, keyboardHookStruct.Time);
  89. }
  90. }
  91. }
  92. }