You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
4.1 KiB

  1. using System;
  2. namespace Apewer.WinForm
  3. {
  4. /// <summary>修饰键。</summary>
  5. public struct ModifierKey : IEquatable<ModifierKey>
  6. {
  7. byte _value;
  8. bool _alt;
  9. bool _ctrl;
  10. bool _shift;
  11. bool _win;
  12. /// <summary>包含 ALT 键。</summary>
  13. public bool WithALT { get => _alt; }
  14. /// <summary>包含 CTRL 键。</summary>
  15. public bool WithCTRL { get => _ctrl; }
  16. /// <summary>包含 SHIFT 键。</summary>
  17. public bool WithSHIFT { get => _shift; }
  18. /// <summary>包含 WIN 键。</summary>
  19. public bool WithWIN { get => _win; }
  20. /// <summary>修饰键组合的值。</summary>
  21. public byte Value { get => _value; }
  22. /// <exception cref="OverflowException"></exception>
  23. private ModifierKey(byte value)
  24. {
  25. _alt = value << 7 >> 7 == 1;
  26. _ctrl = value << 6 >> 7 == 1;
  27. _shift = value << 5 >> 7 == 1;
  28. _win = value << 4 >> 7 == 1;
  29. _value = Convert.ToByte(value);
  30. if (_value != value) throw new OverflowException($"参数【{value}】含有无效的键。");
  31. }
  32. private ModifierKey(bool alt, bool ctrl, bool shift, bool win)
  33. {
  34. _alt = alt;
  35. _ctrl = ctrl;
  36. _shift = shift;
  37. _win = win;
  38. var value = 0;
  39. if (alt) value += 0x01;
  40. if (ctrl) value += 0x02;
  41. if (shift) value += 0x04;
  42. if (win) value += 0x05;
  43. _value = Convert.ToByte(value);
  44. }
  45. /// <summary></summary>
  46. public override int GetHashCode() => _value;
  47. /// <summary></summary>
  48. public override bool Equals(object obj)
  49. {
  50. if (obj is ModifierKey b) return _value == b._value;
  51. return false;
  52. }
  53. /// <summary></summary>
  54. public bool Equals(ModifierKey another) => _value == another._value;
  55. /// <summary></summary>
  56. public static implicit operator byte(ModifierKey instance) => instance._value;
  57. /// <summary></summary>
  58. /// <exception cref="OverflowException"></exception>
  59. public static implicit operator ModifierKey(byte value) => new ModifierKey(value);
  60. /// <summary></summary>
  61. /// <exception cref="ArgumentException" />
  62. public static ModifierKey operator +(ModifierKey a, ModifierKey b)
  63. {
  64. if (a._alt && b._alt) throw new ArgumentException("相加的两个组合键共同包含了 ALT 键。");
  65. if (a._ctrl && b._ctrl) throw new ArgumentException("相加的两个组合键共同包含了 CTRL 键。");
  66. if (a._shift && b._shift) throw new ArgumentException("相加的两个组合键共同包含了 SHIFT 键。");
  67. if (a._win && b._win) throw new ArgumentException("相加的两个组合键共同包含了 WIN 键。");
  68. var alt = a._alt || b._alt;
  69. var ctrl = a._ctrl || b._ctrl;
  70. var shift = a._shift || b._shift;
  71. var win = a._win || b._win;
  72. return new ModifierKey(alt, ctrl, shift, win);
  73. }
  74. /// <summary></summary>
  75. public static ModifierKey operator -(ModifierKey a, ModifierKey b)
  76. {
  77. var alt = a._alt;
  78. var ctrl = a._ctrl;
  79. var shift = a._shift;
  80. var win = a._win;
  81. if (b._alt) alt = false;
  82. if (b._ctrl) ctrl = false;
  83. if (b._shift) shift = false;
  84. if (b._win) win = false;
  85. return new ModifierKey(alt, ctrl, shift, win);
  86. }
  87. /// <summary>表示 ALT 修饰键。</summary>
  88. public static ModifierKey ALT { get; } = new ModifierKey(0x01);
  89. /// <summary>表示 CTRL 修饰键。</summary>
  90. public static ModifierKey CTRL { get; } = new ModifierKey(0x02);
  91. /// <summary>表示 SHIFT 修饰键。</summary>
  92. public static ModifierKey SHIFT { get; } = new ModifierKey(0x04);
  93. /// <summary>表示 WIN 修饰键。</summary>
  94. public static ModifierKey WIN { get; } = new ModifierKey(0x08);
  95. }
  96. }