Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
A few questions
#1
Hello, I have a few questions, is there an LA alternative to CaptureWindowAndRect from QM?

I am still very new to C# and was going through the LA source code and noticed that some LA windows are created using wpfbuilder, why do these windows open instantly? I have a couple of small projects using wpfbuilder, and sometimes they take up to 6 seconds to open.
#2
Code:
Copy      Help
// script ""

//if (!Capture.WindowAndRect(out var r, CWRNeed.Window, true)) return;
//if (!Capture.WindowAndRect(out var r, CWRNeed.Window, false)) return;
//if (!Capture.WindowAndRect(out var r, CWRNeed.Rect)) return;
//if (!Capture.WindowAndRect(out var r, CWRNeed.WindowAndRect, true)) return;
//if (!Capture.WindowAndRect(out var r, CWRNeed.WindowAndRect, false)) return;

if (!Capture.WindowAndRect(out var r, CWRNeed.WindowOrRect, true)) return;
//if (!Capture.WindowAndRect(out var r, CWRNeed.WindowOrRect, false)) return;
print.it(r);

/// <summary>
///
Helps to capture various objects on screen.
/// </summary>
public static class Capture {
    /// <summary>
    ///
Waits for Shift key and then captures a window or/and rectangle on screen.
    /// </summary>
    ///
<returns>true if captured, false if pressed Esc.</returns>
    ///
<param name="results"></param>
    ///
<param name="need"></param>
    ///
<param name="rectInClient">Get rectangle in window client area.</param>
    ///
<param name="wxyFlags"></param>
    public static bool WindowAndRect(out CWRResults results, CWRNeed need, bool rectInClient = false, WXYFlags wxyFlags = 0) {
        results = default;
        
        var s = need switch {
            CWRNeed.Window => "Press Shift to capture window or control.",
            CWRNeed.Rect => "Shift+mouse move to capture rectangle on screen.",
            CWRNeed.WindowAndRect => "Shift+mouse move to capture rectangle in a window or control.",
            _ => "Press Shift to capture window or control.\nOr Shift+mouse move to capture rectangle in a window or control."
        };
        s += "\nOr press Esc to cancel.";
        using var osd = osdText.showText(s, -1);
        
        wnd w = default, wMain = default;
        bool needWindow = need != CWRNeed.Rect;
        if (needWindow) {
            using var osrw = new osdRect {  };
            osrw.Show();
            for (; ; ) {
                wait.doEvents(12);
                if (keys.isPressed(KKey.Escape)) return false;
                w = wnd.fromMouse(wxyFlags);
                osrw.Rect = w.Rect;
                if (keys.isShift) break;
            }
        }
else {
            for (; ; ) {
                wait.doEvents(12);
                if (keys.isPressed(KKey.Escape)) return false;
                if (keys.isShift) break;
            }
        }

        
        var p = mouse.xy;
        RECT r = new(p.x, p.y, 0, 0);
        
        if (need != CWRNeed.Window) {
            if (needWindow) {
                wMain = w.Window;
                var rw = rectInClient ? wMain.ClientRectInScreen : wMain.Rect;
                unsafe { api.ClipCursor(&rw); }
            }

            
            try {
                //using var osrr = new osdRect { Color = 0xff, Opacity = .5, Rect = r };
                using var osrr = new osdRect { Color = 0xff0000, Thickness = 1, Rect = r };
                osrr.Show();
                for (var r1 = r; ;) {
                    wait.doEvents(12);
                    if (keys.isPressed(KKey.Escape)) return false;
                    if (!keys.isShift) break;
                    p = mouse.xy;
                    r1.right = p.x; r1.bottom = p.y;
                    r = r1; r.Normalize(true);
                    osrr.Rect = r;
                }
            }

            finally { if (needWindow) unsafe { api.ClipCursor(null); } }
            
            if (needWindow && w != wMain) { //if rect spans multiple controls, get top-level window
                var w2 = wnd.fromMouse(wxyFlags);
                if (w2 != w) w = wMain;
            }
        }

        
        if (needWindow && rectInClient) w.MapScreenToClient(ref r);
        
        results = new(w, !r.NoArea, r);
        return true;
    }

    
    unsafe class api : NativeApi {
        [
DllImport("user32.dll")]
        internal static extern bool ClipCursor(RECT* lpRect);
    }
}


/// <summary>
///
Used with <see cref="Capture.WindowAndRect"/>.
/// </summary>
public enum CWRNeed {
    /// <summary>Need only window.</summary>
    Window,
    
    /// <summary>Need only rectangle.</summary>
    Rect,
    
    /// <summary>Need rectangle in window.</summary>
    WindowAndRect,
    
    /// <summary>Need window and optionally rectangle in it.</summary>
    WindowOrRect
}

/// <summary>
///
Used with <see cref="Capture.WindowAndRect"/>.
/// </summary>
public record struct CWRResults(wnd w, bool hasRect, RECT r);
#3
WPF starts slowly. Only the first WPF window in that process; other windows are faster. On most computers the first window should start in less than 1 s.
 
Code:
Copy      Help
// script ""
using System.Windows;
using System.Windows.Controls;

//This script measures the time needed to show a WPF window.

for (int i = 0; i < 2; i++) {
    perf.first();
    timer.after(1, _ => { perf.nw(); }); //when the window is fully loaded, visible and ready for input
    ShowWpfWindow();
    1.s();
}


void ShowWpfWindow() {
    var w = new Window { Title = "WPF window" };
    w.Content = new TextBox();
    w.ShowDialog();
}


//On my new Win11 computer: first time 300 ms, then 45 ms.
//On my old (year 2014) Win10 computer: first time 600 ms, then 50 ms. After long time first time can be 1.8 s.
#4
Thanks it worked great, your test script ran normally, I think some nuget package is making the startup slow, as always thanks for the help.


Forum Jump:


Users browsing this thread: 1 Guest(s)