如果给定 window 句柄,我如何确定 window 句柄是否是 Windows UI 的一部分而不是应用程序?

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

我正在编写一个脚本(在 C# 中,但几乎所有内容都是通过 pinvoke 处理的)找到鼠标指针下的 window 句柄并允许用户对其执行一些操作(主要是自定义- bounded-window-snapping 相关功能)。

我已经达到了它非常好用的地步! 可以移动桌面和任务栏。这当然是我实际上不想让它做的事情。我只希望它在用户创建的 windows 上工作; Chrome、Word、记事本或 Teams。

有没有方便的描述我可以看看?我试过查看 window 样式或 PID,但我没有看到关于如何检测“此 'window' 由 Windows shell 拥有的明显模式".

我意识到 -- 我已经检查过 window 句柄是否属于 explorer.exe,但这不起作用,因为它会阻止用户移动常规文件浏览器。

经过一番挖掘,我发现 this question 引用了“GetDesktopWindow()”和“GetShellWindow()”pinvoke 函数。使用 GetShellWindow() api 及其 pid,我能够确定 windows shell 的进程 ID,并将其与我当前正在移动的应用程序的进程 ID 进行比较。最后,由于文件资源管理器 windows 是资源管理器进程的一部分,我检查了 window 是否有“文件资源管理器”作为标题,或者是否有任何一个是 parent windows做。

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