I'm writing a script (in C#, but almost everything is handled via pinvoke) that finds the window handle under the mouse pointer and allows the user to take some action on it (primarily custom-bounded-window-snapping related functionality).
I've got it to the point where it works really really well! It can move the desktop and taskbar. This is of course, something I don't actually want it to do. I only want it to work on windows the user has brought into being; things like Chrome, Word, Notepad, or Teams.
Is there some handy delineation I can look at? I've tried looking at window styles, or PID, but I don't see an obvious pattern on how to detect "this 'window' is owned by the Windows shell".
I realized -- I have checked to see if the window handle belongs to explorer.exe
, but that doesn't work as it prevents the user from moving regular file browsers.
After some digging, I found this question which references the "GetDesktopWindow()" and "GetShellWindow()" pinvoke functions. Using the GetShellWindow() api and it's pid, I was able to determine the process ID of the windows shell, and compare it to the process ID of the application I was currently moving. Finally, since file explorer windows are part of the explorer process, I checked to see if the window has "File Explorer" as it's title, or if any of it's parent windows do.
[DllImport("user32.dll", SetLastError = false)]
private static extern IntPtr GetShellWindow();
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out IntPtr lpdwProcessId);
public bool IsPartOfWindowsUI
{
get
{
var desktopwindow = new WindowRef(GetShellWindow());
return (desktopwindow.ThreadProcessID == ThreadProcessID &&
//Check to see if title of this window or it's parents are
//Basic file explorer windows
!TitleTree.Contains("File Explorer"));
}
}