/// <summary> /// Waits until window exists, is visible (optionally) and active (optionally). /// Returns window handle. On timeout returns default(AWnd) if <i>secondsTimeout</i> is negative; else exception. /// Parameters etc are the same as <see cref="Find"/>. /// </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> /// <exception cref="TimeoutException"><i>secondsTimeout</i> time has expired (if > 0).</exception> /// <exception cref="Exception">Exceptions of <see cref="Find"/>.</exception> /// <remarks> /// By default ignores invisible and cloaked windows. Use flags if need. /// If you have a window's AWnd variable, to wait until it is active/visible/etc use <see cref="WaitForCondition"/> instead. /// </remarks> /// <example> /// <code><![CDATA[ /// AWnd w = AWnd.Wait(10, false, "* Notepad"); /// AOutput.Write(w); /// ]]></code> /// Using in a Form/Control event handler. /// <code><![CDATA[ /// var f = new Form(); /// f.Click += async (unu, sed) => /// { /// AOutput.Write("waiting for Notepad..."); /// AWnd w = await Task.Run(() => AWnd.Wait(-10, false, "* Notepad")); /// if(w.Is0) AOutput.Write("timeout"); else AOutput.Write(w); /// }; /// f.ShowDialog(); /// ]]></code> /// </example> public static AWnd Wait(double secondsTimeout, bool active, #pragma warning disable CS1573 // Parameter has no matching param tag in the XML comment (but other parameters do) [ParamString(PSFormat.AWildex)] string name = null, [ParamString(PSFormat.AWildex)] string cn = null, [ParamString(PSFormat.AWildex)] WOwner of = default, WFlags flags = 0, Func <AWnd, bool> also = null, WContains contains = default) #pragma warning restore CS1573 // Parameter has no matching param tag in the XML comment (but other parameters do) { var f = new Finder(name, cn, of, flags, also, contains); var to = new AWaitFor.Loop(secondsTimeout); for (; ;) { if (active) { AWnd w = Active; if (f.IsMatch(w) && !w.IsMinimized) { return(w); } } else { if (f.Find()) { return(f.Result); } } if (!to.Sleep()) { return(default);
//rejected: single overload with last parameter double? wait. // Then in scripts almost always would need eg ' , wait: 1'. Or would need ', wait: 0' just for 'exception if not found'. #pragma warning disable CS1573 // Parameter has no matching param tag in the XML comment (but other parameters do) /// <summary> /// Finds a top-level window and returns its handle as <b>wnd</b>. Can wait and throw <b>NotFoundException</b>. /// </summary> /// <returns>Window handle. If not found, throws exception or returns <c>default(wnd)</c> (if <i>waitS</i> negative).</returns> /// <param name="waitS">The wait timeout, seconds. If 0, does not wait. If negative, does not throw exception when not found.</param> /// <exception cref="NotFoundException" /> /// <exception cref="ArgumentException" /> /// <inheritdoc cref="find"/> public static wnd find( double waitS, [ParamString(PSFormat.Wildex)] string name = null, [ParamString(PSFormat.Wildex)] string cn = null, [ParamString(PSFormat.Wildex)] WOwner of = default, WFlags flags = 0, Func <wnd, bool> also = null, WContains contains = default ) => new wndFinder(name, cn, of, flags, also, contains).Find(waitS);
#pragma warning restore CS1573 // Parameter has no matching param tag in the XML comment (but other parameters do) //rejected: probably most users will not understand/use it. It's easy and more clear to create and use wndFinder instances. ///// <summary> ///// Gets arguments and result of this thread's last call to <see cref="Find"/> or <see cref="FindAll"/>. ///// </summary> ///// <remarks> ///// <b>wnd.wait</b> and similar functions don't change this property. <see cref="FindOrRun"/> and some other functions of this library change this property because they call <see cref="Find"/> internally. ///// </remarks> ///// <example> ///// This example is similar to what <see cref="FindOrRun"/> does. ///// <code><![CDATA[ ///// wnd w = wnd.find("*- Notepad", "Notepad"); ///// if(w.Is0) { run.it("notepad.exe"); w = wnd.waitAny(60, true, wnd.LastFind).w; } ///// ]]></code> ///// </example> //[field: ThreadStatic] //public static wndFinder lastFind { get; set; } //CONSIDER: add property: [field: ThreadStatic] public static wnd last { get; set; } /// <summary> /// Finds all matching windows. /// Returns array containing 0 or more window handles as wnd. /// Parameters etc are the same as <see cref="find"/>. /// </summary> /// <exception cref="Exception">Exceptions of <see cref="find"/>.</exception> /// <remarks> /// The list is sorted to match the Z order, however hidden windows (when using <see cref="WFlags.HiddenToo"/>) and IME windows are always after visible windows. /// </remarks> /// <seealso cref="getwnd.allWindows"/> /// <seealso cref="getwnd.mainWindows"/> /// <seealso cref="getwnd.threadWindows"/> public static wnd[] findAll( [ParamString(PSFormat.Wildex)] string name = null, [ParamString(PSFormat.Wildex)] string cn = null, [ParamString(PSFormat.Wildex)] WOwner of = default, WFlags flags = 0, Func <wnd, bool> also = null, WContains contains = default) { var f = new wndFinder(name, cn, of, flags, also, contains); var a = f.FindAll(); //LastFind = f; return(a); }
#pragma warning disable CS1573 // Parameter has no matching param tag in the XML comment (but other parameters do) /// <summary> /// Waits until window exists or is active. /// </summary> /// <returns>Window handle. On timeout returns default(wnd) if <i>secondsTimeout</i> is negative; else exception.</returns> /// <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> /// <exception cref="TimeoutException"><i>secondsTimeout</i> time has expired (if > 0).</exception> /// <exception cref="ArgumentException" /> /// <remarks> /// Parameters etc are the same as <see cref="find"/>. /// By default ignores invisible and cloaked windows. Use <i>flags</i> if need. /// If you have a window's <b>wnd</b> variable, to wait until it is active/visible/etc use <see cref="WaitFor"/> instead. /// </remarks> /// <example> /// <code><![CDATA[ /// wnd w = wnd.wait(10, false, "* Notepad"); /// print.it(w); /// ]]></code> /// Using in a WPF window with async/await. /// <code><![CDATA[ /// using System.Windows; /// var b = new wpfBuilder("Window").WinSize(250); /// b.R.AddButton("Wait", async _ => { /// print.it("waiting for Notepad..."); /// wnd w = await Task.Run(() => wnd.wait(-10, false, "* Notepad")); /// if(w.Is0) print.it("timeout"); else print.it(w); /// }); /// if (!b.ShowDialog()) return; /// ]]></code> /// </example> /// <inheritdoc cref="find"/> public static wnd wait(double secondsTimeout, bool active, [ParamString(PSFormat.Wildex)] string name = null, [ParamString(PSFormat.Wildex)] string cn = null, [ParamString(PSFormat.Wildex)] WOwner of = default, WFlags flags = 0, Func <wnd, bool> also = null, WContains contains = default ) => new wndFinder(name, cn, of, flags, also, contains).Wait(secondsTimeout, active);