static KKey _WaitForKey(double secondsTimeout, KKey key, bool up, bool block) { //SHOULDDO: if up and block: don't block if was down when starting to wait. Also in the Mouse func. KKey R = 0; using (WindowsHook.Keyboard(x => { if (key != 0 && !x.IsKey(key)) { return; } if (x.IsUp != up) { if (up && block) //key down when waiting for up. If block, now block down too. { if (key == 0) { key = x.vkCode; } x.BlockEvent(); } return; } R = x.vkCode; //info: for mod keys returns left/right if (block) { x.BlockEvent(); } })) wait.forMessagesAndCondition(secondsTimeout, () => R != 0); return(R); }
/// <summary> /// Waits for keyboard events using callback function. /// </summary> /// <returns> /// Returns the key code. On timeout returns 0 if <i>secondsTimeout</i> is negative; else exception. /// For modifier keys returns the left or right key code, for example LCtrl/RCtrl, not Ctrl. /// </returns> /// <param name="secondsTimeout">Timeout, seconds. Can be 0 (infinite), >0 (exception) or <0 (no exception). More info: [](xref:wait_timeout).</param> /// <param name="f">Callback function that receives key down and up events. Let it return true to stop waiting.</param> /// <param name="block">Make the key down event invisible for other apps (when the callback function returns true).</param> /// <remarks> /// Waits for key event, not for key state. /// Uses low-level keyboard hook. /// Ignores key events injected by functions of this library. /// </remarks> /// <example> /// Wait for F3 or Esc. /// <code><![CDATA[ /// var k = keys.waitForKeys(0, k => !k.IsUp && k.Key is KKey.F3 or KKey.Escape, block: true); /// print.it(k); /// ]]></code> /// </example> public static KKey waitForKeys(double secondsTimeout, Func <HookData.Keyboard, bool> f, bool block = false) { KKey R = 0; using (WindowsHook.Keyboard(x => { if (!f(x)) { return; } R = x.vkCode; //info: for mod keys returns left/right if (block && !x.IsUp) { x.BlockEvent(); } })) wait.forMessagesAndCondition(secondsTimeout, () => R != 0); return(R); }
void _Thread() { _tid = Api.GetCurrentThreadId(); WindowsHook hookK = null, hookM = null; if (_usedEvents.Has(UsedEvents.Keyboard)) { hookK = WindowsHook.Keyboard(_KeyboardHookProc); //note: if lambda, very slow JIT on first hook event } if (_usedEvents.Has(UsedEvents.Mouse)) { hookM = WindowsHook.MouseRaw_(_MouseHookProc); } if (_usedEvents.Has(UsedEvents.MouseEdgeMove)) { _emDetector = new MouseTriggers.EdgeMoveDetector_(); } //tested: don't need JIT-compiling. nint idTimer = (hookK != null || hookM != null) ? Api.SetTimer(default, 0, 10_000, null) : 0;