我想出了一种在 C# 中执行此操作的方法。在可能的Win+L按键序列中涉及四种状态(无Win、、Win+ L、L)。每当达到Win+L状态时,设置一个标志(下面的“winLSet”)。每当释放所有键时,我们都会检查此标志并模拟按下是否已设置。
Ctrl难题的最后一块是在- L(没有 KeyDown)之前模拟 WinKey 的 KeyUp 。我在 AutoHotkey 中尝试过类似的方法,但它从未奏效,但它似乎在这里完美地工作。
代码如下。如果您打算使用此代码,请参阅底部的解释性说明。
public partial class MainWindow : Window
{
LowLevelKeyboardHook hook;
bool winKeyDown;
bool lKeyDown;
bool winLSet;
public MainWindow()
{
InitializeComponent();
hook = new LowLevelKeyboardHook();
hook.KeyDown += OnKeyDown;
hook.KeyUp += OnKeyUp;
}
void OnKeyDown(object sender, LowLevelKeyEventArgs e)
{
e.EventHandled = true;
switch (e.Key)
{
case Key.L:
lKeyDown = true;
UpdateWinLState();
e.EventHandled = winKeyDown;
break;
case Key.LWin:
winKeyDown = true;
UpdateWinLState();
InputSimulator.SimulateKeyDown(VirtualKeyCode.LCONTROL);
break;
case Key.LeftCtrl:
InputSimulator.SimulateKeyDown(VirtualKeyCode.LWIN);
break;
default:
e.EventHandled = false;
break;
}
}
void OnKeyUp(object sender, LowLevelKeyEventArgs e)
{
e.EventHandled = true;
switch (e.Key)
{
case Key.L:
lKeyDown = false;
UpdateWinLState();
e.EventHandled = winKeyDown;
break;
case Key.LWin:
winKeyDown = false;
UpdateWinLState();
InputSimulator.SimulateKeyUp(VirtualKeyCode.LCONTROL);
break;
case Key.LeftCtrl:
InputSimulator.SimulateKeyUp(VirtualKeyCode.LWIN);
break;
default:
e.EventHandled = false;
break;
}
}
void UpdateWinLState()
{
if (winKeyDown && lKeyDown)
{
winLSet = true;
}
else if (!winKeyDown && !lKeyDown && winLSet)
{
winLSet = false;
InputSimulator.SimulateKeyUp(VirtualKeyCode.LWIN);
InputSimulator.SimulateModifiedKeyStroke(
VirtualKeyCode.LCONTROL,
(VirtualKeyCode)'L');
}
}
}
对于后代:请注意,此代码使用InputSimulator和 LowLevelKeyboardHook,它们不是来自 .NET Framework。LowLevelKeyboardHook 是我不久前编写的一个类,它将全局 KeyDown 和 KeyUp 事件公开为 C# 事件。这里有类似的例子,这里,还有一堆可以在这里找到。
另请注意,我使用的是 System.Windows.Input.Key,而不是 System.Windows.Forms.Keys,这可能会使某些人感到困惑。System.Windows.Input.Key 是 .NET 3.0 及更高版本中键的新枚举,而 System.Windows.Forms.Keys 是 Windows 窗体的旧枚举。