Search code examples
c#windowsinteroppinvoke

How can I determine if, given a window handle, the window handle is part of the Windows UI as opposed to an application?


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.


Solution

  • 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"));
      }
    }