Как я могу определить, является ли дескриптор окна частью пользовательского интерфейса Windows, а не приложением?

Я пишу скрипт (на С#, но почти все обрабатывается с помощью pinvoke), который находит дескриптор окна под указателем мыши и позволяет пользователю выполнять над ним некоторые действия (в первую очередь функциональность, связанная с пользовательской ограниченной привязкой к окну).

Я довел его до того, что он работает очень хорошо! Он может перемещать рабочий стол и панель задач. Это, конечно, то, чего я на самом деле не хочу. Я хочу, чтобы он работал только с окнами, созданными пользователем; такие как Chrome, Word, Блокнот или Teams.

Есть ли какое-нибудь удобное описание, на которое я могу взглянуть? Я пытался смотреть на стили окон или PID, но я не вижу очевидного шаблона того, как определить, что это «окно» принадлежит оболочке Windows.

Я понял - я проверил, принадлежит ли дескриптор окна explorer.exe, но это не работает, поскольку не позволяет пользователю перемещать обычные файловые браузеры.


person Sidney    schedule 20.08.2020    source источник
comment
Возможно, это поможет: (stackoverflow.com/questions/24320758/)   -  person Ryan Wilson    schedule 20.08.2020
comment
Вам действительно нужно выяснить, где проходит ваша граница... Можно утверждать, что даже блокнот определенно является частью Windows... После этого вопрос должен быть ответным.   -  person Alexei Levenkov    schedule 20.08.2020


Ответы (1)


Немного покопавшись, я нашел этот вопрос который ссылается на функции Pinvoke GetDesktopWindow() и GetShellWindow(). Используя API GetShellWindow() и его pid, я смог определить идентификатор процесса оболочки 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"));
  }
}
person Sidney    schedule 20.08.2020