///// <summary>The hotkey.</summary> //public KHotkey Hotkey { get; private set; } /// <summary> /// Registers a hotkey using API <msdn>RegisterHotKey</msdn>. /// Returns false if fails. Supports <see cref="ALastError"/>. /// </summary> /// <param name="id">Hotkey id. Must be 0 to 0xBFFF. It will be <i>wParam</i> of the <msdn>WM_HOTKEY</msdn> message.</param> /// <param name="hotkey">Hotkey. Can be: string like "Ctrl+Shift+Alt+Win+K", tuple (KMod, KKey), enum KKey, enum Keys, struct KHotkey.</param> /// <param name="window">Window/form that will receive the <msdn>WM_HOTKEY</msdn> message. Must be of this thread. If default, the message must be retrieved in the message loop of this thread.</param> /// <exception cref="ArgumentException">Error in hotkey string.</exception> /// <exception cref="InvalidOperationException">This variable already registered a hotkey.</exception> /// <remarks> /// Fails if the hotkey is currently registered by this or another application or used by Windows. Also if F12. /// A single variable cannot register multiple hotkeys simultaneously. Use multiple variables, for example array. /// </remarks> /// <seealso cref="AKeys.WaitForHotkey"/> /// <example>See <see cref="ARegisteredHotkey"/>.</example> public bool Register(int id, KHotkey hotkey, AnyWnd window = default) { var(mod, key) = hotkey; if (_id != 0) { throw new InvalidOperationException("This variable already registered a hotkey. Use multiple variables or call Unregister."); } var m = mod & ~(KMod.Alt | KMod.Shift); if (mod.Has(KMod.Alt)) { m |= KMod.Shift; } if (mod.Has(KMod.Shift)) { m |= KMod.Alt; } var w = window.Wnd; if (!Api.RegisterHotKey(w, id, (uint)m, key)) { return(false); } _w = w; _id = id; //Hotkey = hotkey; return(true); }
internal static (int mod, KKey key) Normalize_(KHotkey hotkey) { var(mod, key) = hotkey; if (key == KKey.Pause && mod.Has(KMod.Ctrl)) { key = KKey.Break; } //if(key == KKey.NumPad5 && mod.Has(KMod.Shift)) key = KKey.Clear; //Shift+numpad don't work return(Math2.SwapBits((int)mod, 0, 2, 1), key); }
///// <summary>The hotkey.</summary> //public KHotkey Hotkey { get; private set; } /// <summary> /// Registers a hotkey using API <msdn>RegisterHotKey</msdn>. /// Returns false if fails. Supports <see cref="lastError"/>. /// </summary> /// <param name="id">Hotkey id. Must be 0 to 0xBFFF or value returned by API <msdn>GlobalAddAtom</msdn>. It will be <i>wParam</i> of the <msdn>WM_HOTKEY</msdn> message.</param> /// <param name="hotkey">Hotkey. Can be: string like "Ctrl+Shift+Alt+Win+K", tuple <b>(KMod, KKey)</b>, enum <b>KKey</b>, enum <b>Keys</b>, struct <b>KHotkey</b>.</param> /// <param name="window">Window/form that will receive the <msdn>WM_HOTKEY</msdn> message. Must be of this thread. If default, the message must be retrieved in the message loop of this thread.</param> /// <exception cref="ArgumentException">Error in hotkey string.</exception> /// <exception cref="InvalidOperationException">This variable already registered a hotkey.</exception> /// <remarks> /// Fails if the hotkey is currently registered by this or another application or used by Windows. Also if F12. /// <note>Most single-key and Shift+key hotkeys don't work when the active window has higher UAC integrity level (eg admin) than this process. Media keys may work.</note> /// A single variable cannot register multiple hotkeys simultaneously. Use multiple variables, for example array. /// </remarks> /// <seealso cref="keys.waitForHotkey"/> public bool Register(int id, [ParamString(PSFormat.Hotkey)] KHotkey hotkey, AnyWnd window = default) { if (_id != 0) { throw new InvalidOperationException("This variable already registered a hotkey. Use multiple variables or call Unregister."); } var w = window.Hwnd; var(mod, key) = Normalize_(hotkey); if (!Api.RegisterHotKey(w, id, mod, key)) { return(false); } _w = w; _id = id; //Hotkey = hotkey; return(true); }
/// <summary> /// Registers a temporary hotkey and waits for it. /// </summary> /// <param name="secondsTimeout">Timeout, seconds. Can be 0 (infinite), >0 (exception) or <0 (no exception). More info: [](xref:wait_timeout).</param> /// <param name="hotkey">Hotkey. Can be: string like "Ctrl+Shift+Alt+Win+K", tuple <b>(KMod, KKey)</b>, enum <b>KKey</b>, enum <b>Keys</b>, struct <b>KHotkey</b>.</param> /// <param name="waitModReleased">Also wait until hotkey modifier keys released.</param> /// <returns>Returns true. On timeout returns false if <i>secondsTimeout</i> is negative; else exception.</returns> /// <exception cref="ArgumentException">Error in hotkey string.</exception> /// <exception cref="AuException">Failed to register hotkey.</exception> /// <exception cref="TimeoutException"><i>secondsTimeout</i> time has expired (if > 0).</exception> /// <remarks> /// Uses <see cref="RegisteredHotkey"/> (API <msdn>RegisterHotKey</msdn>). /// Fails if the hotkey is currently registered by this or another application or used by Windows. Also if F12. /// <note>Most single-key and Shift+key hotkeys don't work when the active window has higher UAC integrity level (eg admin) than this process. Media keys may work.</note> /// </remarks> /// <example> /// <code><![CDATA[ /// keys.waitForHotkey(0, "F11"); /// keys.waitForHotkey(0, KKey.F11); /// keys.waitForHotkey(0, "Shift+A", true); /// keys.waitForHotkey(0, (KMod.Ctrl | KMod.Shift, KKey.P)); //Ctrl+Shift+P /// keys.waitForHotkey(0, Keys.Control | Keys.Alt | Keys.H); //Ctrl+Alt+H /// keys.waitForHotkey(5, "Ctrl+Win+K"); //exception after 5 s /// if(!keys.waitForHotkey(-5, "Left")) print.it("timeout"); //returns false after 5 s /// ]]></code> /// </example> public static bool waitForHotkey(double secondsTimeout, [ParamString(PSFormat.Hotkey)] KHotkey hotkey, bool waitModReleased = false) { if (s_atomWFH == 0) { s_atomWFH = Api.GlobalAddAtom("Au.WaitForHotkey"); } using (RegisteredHotkey rhk = default) { if (!rhk.Register(s_atomWFH, hotkey)) { throw new AuException(0, "*register hotkey"); } if (!wait.forPostedMessage(secondsTimeout, (ref MSG m) => m.message == Api.WM_HOTKEY && m.wParam == s_atomWFH)) { return(false); } } if (waitModReleased) { return(waitForNoModifierKeys(secondsTimeout, hotkey.Mod)); } return(true); }