I want to read out all windows of a process. Then I want to check for all windows which have a bounds area > 0. These are the windows I want to work with but they should be visible. Now I have two problems:
- When I check the windows of spotify.exe I get multiple windows with an area > 0, but I know there is only one correct window.
Here the code:
[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:
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
When I look at the values it seems that the 3rd one is the correct one. Why can other window handles have an area when they are not visible or minimized?
- When I try to read out the windows of Windows Movies & TV all windows are 0,0,0,0. But I clearly see the window is visible on my 2nd screen so it should have an area. I use the same code, but instead of
if (p.ProcessName == "Spotify")
I useif (p.MainModule.FileName.Contains("WindowsApps") && p.MainModule.FileName.Contains("Video.UI.exe"))
Output:
1117438: 0 0 0 0
3150042: 0 0 0 0
Any Ideas?
P.S.: I don't use p.MainWindowHandle because it's too inconsequent. Sometimes it's 0 sometimes not. Depends on User interaction, windows visibility, ... So it's too unreliable. For Windows Movies & TV it's always 0.