Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I figured out a way to do this in C#. There are four states involved in a possible <kbd>Win</kbd>+<kbd>L</kbd> keypress sequence (None, <kbd>Win</kbd>, <kbd>Win</kbd>+<kbd>L</kbd>, <kbd>L</kbd>). Whenever the <kbd>Win</kbd>+<kbd>L</kbd> 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.</p> <p>The final piece of the puzzle is to simulate the WinKey's KeyUp before the <kbd>Ctrl</kbd>-<kbd>L</kbd> (no KeyDown). I've tried similar approaches in AutoHotkey and it never worked, but it seems to work perfectly here.</p> <p>The code is below. Please see explanatory notes at the bottom if you plan to use this code.</p> <pre><code>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 &amp;&amp; lKeyDown) { winLSet = true; } else if (!winKeyDown &amp;&amp; !lKeyDown &amp;&amp; winLSet) { winLSet = false; InputSimulator.SimulateKeyUp(VirtualKeyCode.LWIN); InputSimulator.SimulateModifiedKeyStroke( VirtualKeyCode.LCONTROL, (VirtualKeyCode)'L'); } } } </code></pre> <p>For posterity: please note that this code uses <a href="http://inputsimulator.codeplex.com/" rel="nofollow noreferrer">InputSimulator</a> and LowLevelKeyboardHook, which are not from the .NET Framework. LowLevelKeyboardHook is a class I wrote a while back that exposes global KeyDown and KeyUp events as C# events. There are similar examples <a href="http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx" rel="nofollow noreferrer">here</a>, <a href="http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx" rel="nofollow noreferrer">here</a>, and a bunch can be found <a href="http://www.google.com/search?hl=en&amp;q=low+level+keyboard+hook+c%23&amp;aq=f&amp;aqi=&amp;aql=&amp;oq=&amp;gs_rfai=" rel="nofollow noreferrer">here</a>.</p> <p>Also notice that I'm using System.Windows.Input.Key, not System.Windows.Forms.Keys, which could confuse some people. System.Windows.Input.Key is the new enumeration of keys in .NET 3.0 and above, while System.Windows.Forms.Keys is the old enumeration from Windows Forms.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload