Подтвердить что ты не робот

Каковы различия между BringWindowToTop, SetForegroundwindow, SetWindowPos и ​​т.д.?

BringWindowToTop, SetForegroundWindow, SwitchToThisWindow, SetWindowPos, ShowWindow все описаны как отображение и активация окна.

Каковы реальные различия между ними? Когда и почему BringWindowToTop предпочтительнее SetForegroundWindow или SwitchToThisWindow или даже SetWindowPos с флагами, установленными для активации и отображения?

4b9b3361

Ответ 1

Здесь задействовано много тесно связанных понятий, и связанные термины часто используются неправильно, даже в официальной документации.

Важные типы окон:

  • окна верхнего уровня: окна без родительского окна. Главное окно приложения - это почти всегда окно верхнего уровня. Это не имеет ничего общего с z-порядком.

  • дочерние окна: Windows, которые содержатся в родительском окне. Их положение всегда относительно родительской области окна. Дочерние окна часто являются "элементами управления": такие вещи, как кнопки и поля редактирования.

  • родительские окна: окна с дочерними окнами. Окна верхнего уровня часто имеют детей. Но обратите внимание, что дочерние окна также могут иметь дочерние и, следовательно, быть родительскими и дочерними окнами.

  • собственные окна: окна, которые управляются другим окном, но не обязательно являются дочерними для другого окна. Примером является плавающая палитра инструментов: она принадлежит другому окну в приложении, но не привязана к этой другой области окна.

  • владелец окна: Windows, которому принадлежит собственное окно.

Часто различие между отношениями владелец/владелец и отношениями родитель/потомок не имеет значения, поэтому термины родитель и потомок часто используются для обоих контекстов, даже в документации. В некоторых случаях родительские поля и параметры перегружаются, чтобы обозначить родителя и/или владельца.

Важные понятия:

  • top of z-order: буквально означает окно, которое отображается над другими окнами.

  • активное окно: нечеткая концепция, но обычно это окно верхнего уровня, которое пользователь будет рассматривать как "текущее" окно. Активное окно обычно рисуется с отличительной границей, и его плитка на панели задач выделяется. Активное окно обычно находится в верхней части z-порядка или близко к нему среди всех других окон верхнего уровня, и оно является родителем или владельцем (возможно, косвенно) окна с фокусом клавиатуры.

  • фокус клавиатуры: указывает окно, которое будет получать сообщения клавиатуры. Концептуально, есть одно окно с фокусом клавиатуры. Часто окно с фокусом является дочерним элементом (или внуком и т.д.) Активного окна.

  • передний план: активное окно обычно находится на переднем плане. Похоже, что имя предполагает, что оно находится в верхней части z-порядка, но на самом деле это означает, что поток, создавший окно, получает небольшое повышение приоритета. Это активное окно обычно также является окном переднего плана.

Допустим, у вас открыто окно браузера и запущен экземпляр Notepad. Если щелкнуть документ в Блокноте, произойдет целый поток сообщений и изменений состояния. На самом деле вы нажимаете на большое поле редактирования, которое является дочерним окном окна верхнего уровня Блокнота. Этот щелчок вызывает активацию поля редактирования, но дочерние окна не могут быть "активным" окном, поэтому он просто берет фокус клавиатуры и передает сообщение активации через своих предков, пока не попадет в окно верхнего уровня. Окно верхнего уровня "активируется", перемещаясь в верхнюю часть z-порядка, выделяя его границу и т.д. Оно также становится окном переднего плана, поэтому его поток получает небольшой импульс, чтобы сделать пользовательский интерфейс немного более отзывчивым, чем любой другой. окна.

Имея в виду эти термины, вы можете проанализировать описания MSDN для функций, которые вы перечислили, чтобы выявить тонкие различия.

Если вы пытаетесь расположить своих дочерних окон, просто используйте SetWindowPos (или MoveWindow, SizeWindow и ShowWinow). Из остальных функций SwitchToThisWindow выглядит устаревшим и, по сути, таким же, как SetForegroundWindow. (Обратите внимание, что во многих случаях SetForegroundWindow не будет делать то, что вы хотите, если вы не являетесь активным приложением или активное приложение не предоставило вам разрешение на его использование.) BringWindowToTop в основном сводится к переносу окна в верхнюю часть z- порядок (который вы можете сделать с SetWindowPos), с дополнительными побочными эффектами, которые заставляют его вести себя как SetForegroundWindow, если вы вызываете его в окне верхнего уровня.

Обновление: Раймонд Чен опубликовал более четкое различие между активным окном и окном переднего плана. Цитировать:

Концепция окна переднего плана была введена, когда ввод был десинхронизирован, чтобы выразить "действительно глобальное активное окно", в отличие от SetActiveWindow, которое продолжало ссылаться на локальное активное окно.

Ответ 2

Используйте setwindowpos, если вам нужно изменить размер окна (а не только его состояние)

Используйте showwindow для изменения только состояния окна

Используйте bringwindowtotop для активации родительского окна через дочерний элемент. если вы отправите ему дочернее окно (возможно, плавающую панель инструментов), родитель будет перенесен на передний план и будет иметь фокус вместо дочернего элемента.

Все они имеют свое место и, очевидно, имеют повторяющиеся функциональные возможности, но каждый из них немного отличается в зависимости от того, что вы хотите сделать.