/// <summary> /// Waits while some modifier keys (Ctrl, Shift, Alt, Win) or mouse buttons are pressed. /// </summary> /// <param name="secondsTimeout">Timeout, seconds. Can be 0 (infinite), >0 (exception) or <0 (no exception). More info: [](xref:wait_timeout).</param> /// <param name="mod">Check only these keys. Default: all.</param> /// <param name="buttons">Check only these buttons. Default: all.</param> /// <returns>Returns true. On timeout returns false if <i>secondsTimeout</i> is negative; else exception.</returns> /// <exception cref="TimeoutException"><i>secondsTimeout</i> time has expired (if > 0).</exception> /// <seealso cref="isMod"/> /// <seealso cref="mouse.isPressed"/> /// <seealso cref="mouse.waitForNoButtonsPressed"/> public static bool waitForNoModifierKeysAndMouseButtons(double secondsTimeout = 0.0, KMod mod = KMod.Ctrl | KMod.Shift | KMod.Alt | KMod.Win, MButtons buttons = MButtons.Left | MButtons.Right | MButtons.Middle | MButtons.X1 | MButtons.X2) { var to = new wait.Loop(secondsTimeout, new OWait(period: 2)); for (; ;) { if (!isMod(mod) && !mouse.isPressed(buttons)) { return(true); } if (!to.Sleep()) { return(false); } } }
/// <summary> /// Opens again. /// Must be closed. /// Owner window should be not destroyed; does not create again. /// </summary> /// <param name="noThrow">If fails, return false, no exception. Also then waits 1 s instead of 10 s.</param> /// <exception cref="AuException">Failed to open.</exception> public bool Reopen(bool noThrow = false) { Debug.Assert(!_isOpen); var to = new wait.Loop(noThrow ? -1 : -10, new OWait(period: 1)); while (!Api.OpenClipboard(_w)) { int ec = lastError.code; if (!to.Sleep()) { Dispose(); if (noThrow) { return(false); } throw new AuException(ec, "*open clipboard"); } } _isOpen = true; return(true); }
#pragma warning restore CS1573 // Parameter has no matching param tag in the XML comment (but other parameters do) /// <summary> /// Waits until any of specified windows exists or is active. /// </summary> /// <param name="secondsTimeout">Timeout, seconds. Can be 0 (infinite), >0 (exception) or <0 (no exception). More info: [](xref:wait_timeout).</param> /// <param name="active">The window must be the active window (<see cref="active"/>), and not minimized.</param> /// <param name="windows">Specifies windows, like <c>new("Window1"), new("Window2")</c>.</param> /// <returns>1-based index and window handle. On timeout returns <c>(0, default(wnd))</c> if <i>secondsTimeout</i> is negative; else exception.</returns> /// <exception cref="TimeoutException"><i>secondsTimeout</i> time has expired (if > 0).</exception> /// <remarks> /// By default ignores invisible and cloaked windows. Use <b>wndFinder</b> flags if need. /// </remarks> /// <example> /// <code><![CDATA[ /// var (i, w) = wnd.waitAny(10, true, "* Notepad", new wndFinder("* Word")); /// print.it(i, w); /// ]]></code> /// </example> public static (int index, wnd w) waitAny(double secondsTimeout, bool active, params wndFinder[] windows) { foreach (var f in windows) { f.Result = default; } WFCache cache = active && windows.Length > 1 ? new WFCache() : null; var to = new wait.Loop(secondsTimeout); for (; ;) { if (active) { wnd w = wnd.active; for (int i = 0; i < windows.Length; i++) { if (windows[i].IsMatch(w, cache) && !w.IsMinimized) { return(i + 1, w); } } } else { for (int i = 0; i < windows.Length; i++) { var f = windows[i]; if (f.Exists()) { return(i + 1, f.Result); } } //FUTURE: optimization: get list of windows once (Lib.EnumWindows2). // Problem: list filtering depends on wndFinder flags. Even if all finders have same flags, its easy to make bugs. } if (!to.Sleep()) { return(default);