В Windows должно ли мое дочернее окно получить WM_WINDOWPOSCHANGED, когда его z-порядок изменяется относительно одного из его братьев и сестер? - PullRequest
2 голосов
/ 14 июня 2011

Я пытаюсь вставить пользовательский виджет в строку URL-адреса Internet Explorer 8 рядом с кнопками остановки и перезагрузки. Это просто личный усилитель производительности для меня.

«Модель окна» для этой части фрейма IE представляет собой «корневое окно адресной строки», которому принадлежат окна, которые включают в себя строку URL-адреса IE8: поле редактирования, комбинированный элемент управления и кнопки остановки и перезагрузки.

Из другого процесса я создаю новое окно WS_CHILD (с пользовательским именем класса), которое связано с корневым окном адресной строки IE, что делает его одним из элементов окна редактирования и остановки / перезагрузки. Я вызываю SetWindowPos с hwndInsertAfter из HWND_TOP, чтобы убедиться, что он отображается «над» (т. Е. «В») на панели URL. Это хорошо работает, и я вижу, что мое окно изначально нарисовано внутри urlbar IE.

Однако, когда я активирую окно IE, элемент управления urlbar откатывается назад перед моим окном. Я знаю, что это происходит, потому что я все еще вижу, что мое окно закрашено за панелью url, и потому, что когда я печатаю -> GetTopWindow () на консоли отладки по таймеру, оно становится HWND элемента управления редактированием urlbar.

Если я обновлю свой цикл сообщений, чтобы вызвать SetWindowPos с HWND_TOP на WM_PAINT, все будет лучше - теперь, когда я активирую окно IE и перемещаю его, мой элемент управления должным образом остается над элементом управления редактирования в URL-адрес. Однако, как только я переключаюсь между вкладками IE, которые обновляют текст элемента управления Edit urlbar IE, мой элемент управления переходит за элемент управления Edit. (Примечание: это также происходит, когда я увеличиваю или восстанавливаю окно.)

Итак, мои вопросы:

1) Вполне вероятно, что IE намеренно помещает свой элемент управления urlbar для редактирования обратно поверх z-порядка каждый раз, когда вы нажимаете на вкладку в IE, или есть пробел в моем понимании того, как рисовать Windows и z- заказ работ? Насколько я понимаю, если вы укажете z-упорядочение дочерних окон (которые не могут быть изменены конечным пользователем), это упорядочение должно сохраняться до тех пор, пока не будет изменено программно. Таким образом, даже если IE перерисовывает свой элемент управления «Правка» при выборе вкладки, тогда как я не перерисовываю или иным образом не воздействую на мое окно, мое окно должно по-прежнему оставаться твердо наверху.

2) Учитывая, что z-порядок моего окна, по-видимому, меняется, не должно ли оно получить WM_WINDOWPOSCHANGING / WM_WINDOWPOSCHANGED? Если бы это было так, я мог бы хотя бы отреагировать на это событие и остаться на вершине элемента управления «Редактировать». Но даже при том, что я вижу, как рисует мое окно за элементом управления «Редактировать» на URL-панели, когда я нажимаю на вкладку, и даже несмотря на то, что выходные данные моего окна отладки подтверждают, что GetTopWindow () корня адресной строки становится HWND элемента управления «Редактировать», когда я нажимаю на вкладку и хотя я вижу, что WM_WINDOWPOSCHANGING / WM_WINDOWPOSCHANGED отправляется в элемент управления Edit с hwndInsertAfter из HWND_TOP, когда я щелкаю по вкладке, мое собственное окно не получает никаких сообщений, которые позволили бы мне сохранить постоянный z-порядок. Это кажется мне неправильным, и решение этой проблемы вынудит меня запустить процесс IE и перехватить все сообщения, отправленные на его элемент управления Edit, просто чтобы получить событие, на которое нужно ответить: (

Спасибо за помощь!

1 Ответ

2 голосов
/ 15 июня 2011
  1. Вполне вероятно, что IE изменяет Z-порядок элементов управления при смене вкладок. В IE9 панель URL и вкладки имеют общего родителя. Когда вы выбираете новую вкладку, она активирует панель URL (и активация обычно приводит окно к вершине его локального Z-порядка).

  2. Нет. Вы получаете WM_WINDOWPOSCHANGED, когда функция SetWindowPos действует на ваше окно. Если у некоторых братьев и сестер изменились z-порядки, вы не получите сообщение. Никто не вызывал SetWindowPos в вашем окне. Вы можете убедиться в этом, написав тестовую программу, которая управляет z-порядком некоторых дочерних окон.

Это имеет смысл, потому что может быть произвольное количество окон-братьев и сестер, и может потребоваться неограниченное количество служебных данных для уведомления всех из них. Также было бы почти невозможно придумать согласованный набор правил для доставки этих сообщений всем братьям и сестрам, учитывая, что некоторые братья и сестры могли бы реагировать, перетасовывая z-порядок. Есть ли у братьев и сестер, которые еще не получили первое уведомление, два ожидающих уведомления? Они немедленно отправлены или отправлены? Что, если очередь растет и растет до тех пор, пока не переполнится?

Это отличается от уведомлений WM_KILLFOCUS / WM_SETFOCUS тем, что оно затрагивает не более двух окон. Это накладывает разумное ограничение на количество уведомлений. Даже если существует бесконечный бесконечный цикл, потому что проигравший элемент управления пытается вернуть фокус обратно, очередь не переполнится, потому что для каждого доставленного WM_KILLFOCUS имеется только один вызов SetFocus.

Кроме того, вполне разумно, чтобы окна реагировали на потерю фокуса. Гораздо менее вероятно, что окно C должно знать, что B теперь находится над A, а не наоборот, так зачем проектировать систему для отправки миллионов ненужных сообщений?

Взламывание пользовательского интерфейса приложений, которые вы не контролируете и у которых нет четко определенных API-интерфейсов для выполнения типов задач, которые вы хотите сделать, находится где угодно, от трудного до невозможного, и это всегда хрупко. В группах, в которых используются панели инструментов и настройки браузера, работает больше людей, чем вы могли ожидать, и они проводят большую часть своего дня, исследуя Spy ++ и экспериментируя. Это от природы хакерство.

...