I figured out a way to do this in C#. There are four states involved in a possible Win+L keypress sequence (None, Win, Win+L, L). Whenever the Win+L state is reached, set a flag ("winLSet" below). Whenever all of the keys have been released, we check for this flag and simulate the press if it's been set.
The final piece of the puzzle is to simulate the WinKey's KeyUp before the Ctrl-L (no KeyDown). I've tried similar approaches in AutoHotkey and it never worked, but it seems to work perfectly here.
代码如下。如果您打算使用此代码,请参阅底部的解释说明。
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');
}
}
}
对于后代:请注意此代码使用输入模拟器 https://www.microsoft.com/nl-nl/?p=inputsimulator和 LowLevelKeyboardHook,它们不是来自 .NET Framework。 LowLevelKeyboardHook 是我不久前编写的一个类,它将全局 KeyDown 和 KeyUp 事件公开为 C# 事件。类似的例子还有here https://web.archive.org/web/20160217145327/http://blogs.msdn.com:80/b/toub/archive/2006/05/03/589423.aspx, here https://web.archive.org/web/20160105234529/http://www.codeproject.com:80/KB/cs/CSLLKeyboardHook.aspx,并且可以找到一堆.
另请注意,我使用的是 System.Windows.Input.Key,而不是 System.Windows.Forms.Keys,这可能会让某些人感到困惑。 System.Windows.Input.Key 是 .NET 3.0 及更高版本中新的键枚举,而 System.Windows.Forms.Keys 是 Windows 窗体中的旧枚举。