diff --git a/Apewer.Windows/WinForm/ModifierKey.cs b/Apewer.Windows/WinForm/ModifierKey.cs
new file mode 100644
index 0000000..05610f5
--- /dev/null
+++ b/Apewer.Windows/WinForm/ModifierKey.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Apewer.WinForm
+{
+
+ /// 修饰键。
+ public struct ModifierKey : IEquatable
+ {
+
+ byte _value;
+ bool _alt;
+ bool _ctrl;
+ bool _shift;
+ bool _win;
+
+ /// 包含 ALT 键。
+ public bool WithALT { get => _alt; }
+
+ /// 包含 CTRL 键。
+ public bool WithCTRL { get => _ctrl; }
+
+ /// 包含 SHIFT 键。
+ public bool WithSHIFT { get => _shift; }
+
+ /// 包含 WIN 键。
+ public bool WithWIN { get => _win; }
+
+ /// 修饰键组合的值。
+ public byte Value { get => _value; }
+
+ ///
+ private ModifierKey(byte value)
+ {
+ _alt = value << 7 >> 7 == 1;
+ _ctrl = value << 6 >> 7 == 1;
+ _shift = value << 5 >> 7 == 1;
+ _win = value << 4 >> 7 == 1;
+ _value = Convert.ToByte(value);
+ if (_value != value) throw new OverflowException($"参数【{value}】含有无效的键。");
+ }
+
+ private ModifierKey(bool alt, bool ctrl, bool shift, bool win)
+ {
+ _alt = alt;
+ _ctrl = ctrl;
+ _shift = shift;
+ _win = win;
+
+ var value = 0;
+ if (alt) value += 0x01;
+ if (ctrl) value += 0x02;
+ if (shift) value += 0x04;
+ if (win) value += 0x05;
+ _value = Convert.ToByte(value);
+ }
+
+ ///
+ public override int GetHashCode() => _value;
+
+ ///
+ public override bool Equals(object obj)
+ {
+ if (obj is ModifierKey b) return _value == b._value;
+ return false;
+ }
+
+ ///
+ public bool Equals(ModifierKey another) => _value == another._value;
+
+ ///
+ public static implicit operator byte(ModifierKey instance) => instance._value;
+
+ ///
+ ///
+ public static implicit operator ModifierKey(byte value) => new ModifierKey(value);
+
+ ///
+ ///
+ public static ModifierKey operator +(ModifierKey a, ModifierKey b)
+ {
+ if (a._alt && b._alt) throw new ArgumentException("相加的两个组合键共同包含了 ALT 键。");
+ if (a._ctrl && b._ctrl) throw new ArgumentException("相加的两个组合键共同包含了 CTRL 键。");
+ if (a._shift && b._shift) throw new ArgumentException("相加的两个组合键共同包含了 SHIFT 键。");
+ if (a._win && b._win) throw new ArgumentException("相加的两个组合键共同包含了 WIN 键。");
+
+ var alt = a._alt || b._alt;
+ var ctrl = a._ctrl || b._ctrl;
+ var shift = a._shift || b._shift;
+ var win = a._win || b._win;
+ return new ModifierKey(alt, ctrl, shift, win);
+ }
+
+ ///
+ public static ModifierKey operator -(ModifierKey a, ModifierKey b)
+ {
+ var alt = a._alt;
+ var ctrl = a._ctrl;
+ var shift = a._shift;
+ var win = a._win;
+
+ if (b._alt) alt = false;
+ if (b._ctrl) ctrl = false;
+ if (b._shift) shift = false;
+ if (b._win) win = false;
+
+ return new ModifierKey(alt, ctrl, shift, win);
+ }
+
+ /// 表示 ALT 修饰键。
+ public static ModifierKey ALT { get; } = new ModifierKey(0x01);
+
+ /// 表示 CTRL 修饰键。
+ public static ModifierKey CTRL { get; } = new ModifierKey(0x02);
+
+ /// 表示 SHIFT 修饰键。
+ public static ModifierKey SHIFT { get; } = new ModifierKey(0x04);
+
+ /// 表示 WIN 修饰键。
+ public static ModifierKey WIN { get; } = new ModifierKey(0x08);
+
+ }
+
+}