Autor Beitrag
Kasko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 117

Win 10
C# C++ (VS 2017/19), (Java, PHP)
BeitragVerfasst: Di 05.01.21 21:23 
Ich möchte alle Fenster eines Prozesses auslesen. Dann möchte ich nach allen Fenstern suchen, deren Fläche > 0 ist. Dies sind die Fenster, mit denen ich arbeiten möchte, die jedoch sichtbar sein sollten. Jetzt habe ich zwei Probleme:

1. Wenn ich die Fenster von spotify.exe überprüfe, erhalte ich mehrere Fenster mit einem Bereich > 0, aber ich weiß, dass es nur ein korrektes Fenster gibt.

Hier der Code:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);

static IEnumerable<IntPtr> EnumerateProcessWindowHandles(int processId) {
    var handles = new List<IntPtr>();

    foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
        EnumThreadWindows(thread.Id,
            (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);

    return handles;
}

[StructLayout(LayoutKind.Sequential)]
public struct RECT {
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

// --main--

foreach (Process p in Process.GetProcesses()) {
    try {
        if (p.ProcessName == "Spotify") {
            foreach (var hwnd in EnumerateProcessWindowHandles(p.Id)) {
                RECT rect = new RECT();

                if (!GetWindowRect(hwnd, out rect)) {
                    Console.WriteLine("Fail");
                    continue;
                }

                Console.WriteLine(string.Format("{0}: {1} {2} {3} {4}", hwnd, rect.Left, rect.Top, rect.Right, rect.Bottom));
            }
        }
    }
    catch (Win32Exception) { }
    catch (InvalidOperationException) { }
}


Output:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
658638: 114 8 154 48
5114512: 1659 0 1794 31
132734: 98 0 1794 900
395348: 0 0 0 0
132744: 0 0 136 39
721406: 26 26 1466 815
132758: 0 0 0 0
854982: 0 0 0 0
132760: 0 0 0 0
132710: 0 0 1 1
198288: 0 0 0 0
132754: 0 0 136 39
198286: 0 0 0 0


Wenn ich mir die Werte ansehe, scheint es, dass das dritte Fenster das richtige ist. Warum können andere Fenster einen Bereich haben, wenn sie nicht sichtbar oder minimiert sind? Sie werden nie gezeigt.

2. Wenn ich versuche, die Fenster von Windows Movies & TV auszulesen, sind alle Fenster 0,0,0,0. Aber ich sehe deutlich, dass das Fenster auf meinem zweiten Bildschirm sichtbar ist, also sollte es einen Fläche haben. Ich verwende denselben Code, aber anstelle von if (p.ProcessName == "Spotify") verwende ich if (p.MainModule.FileName.Contains("WindowsApps") && p.MainModule.FileName.Contains("Video.UI.exe"))

Output:

ausblenden Quelltext
1:
2:
1117438: 0 0 0 0
3150042: 0 0 0 0


Irgendwelche Ideen?

P.S. Ich benutze p.MainWindowHandle nicht, weil es zu inkonsequent ist. Manchmal ist es 0, manchmal nicht. Hängt von der Benutzerinteraktion, der Sichtbarkeit von Fenstern usw. ab. Es ist also zu unzuverlässig. Für Windows Movies & TV ist es immer 0.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18978
Erhaltene Danke: 1679

W10 x64 (Chrome, Edge)
Delphi 10.4 Ent, Oxygene, C# (VS 2019), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 05.01.21 21:43 
Du prüfst die Sichtbarkeit auch gar nicht. Das geht beispielsweise mit IsWindowVisible:
docs.microsoft.com/e...user-iswindowvisible
Kasko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 117

Win 10
C# C++ (VS 2017/19), (Java, PHP)
BeitragVerfasst: Di 05.01.21 21:54 
Ja aber wenn ein Fenster zwar offen und in der Taskleiste zusehen ist, jedoch im Hintergrund ist also verdeckt wird, dann würde IsWindowVisible doch auch false zurückgeben oder nicht.

Edit: Okay doch nicht, jedoch sind bis auf zwei trotzdem noch alle anderen zu sehen, unter anderem auch welche mit einer Fläche von 0,0,0,0