Windows API: Какое первое сообщение гарантированно получит окно? - PullRequest
7 голосов
/ 16 ноября 2009

Я привык думать, что WM_CREATE - это первое сообщение, которое получает окно. Однако при проверке этого предположения в окне верхнего уровня оно оказывается ложным. В моем тесте WM_MINMAXINFO был первым сообщением.

Итак, какое первое сообщение гарантированно получит окно?

Ответы [ 4 ]

15 голосов
/ 16 ноября 2009

WM_NCCREATE на самом деле самое первое сообщение, которое ваше окно получит , которое поступит до WM_CREATE. Это связано с созданием не клиентской области (например, строки заголовка, системного меню и т. Д.), Следовательно, префикс NC.

WM_GETMINMAXINFO отправляется до изменения размера / позиции окна и может прибыть до WM_CREATE (подробнее см. Ниже).

Сообщение WM_CREATE отправляется до возврата CreateWindow(), поэтому вы можете гарантировать, что инициализация для каждого окна была выполнена этой точкой. Ваша оконная процедура получит WM_CREATE после того, как окно будет создано, но до того, как окно станет видимым (WM_SHOWWINDOW).

На самом деле, в документации MSDN есть интересное несоответствие - кажется, что сообщения о создании зависят от того, звоните ли вы CreateWindow() или CreateWindowEx(), однако это не указывает что сообщения обязательно перечислены в порядке отправки.

  • CreateWindow(): WM_CREATE, WM_GETMINMAXINFO и WM_NCCREATE
  • CreateWindowEx(): WM_NCCREATE, WM_NCCALCSIZE и WM_CREATE

Я сильно подозреваю, что порядок сообщений, описанный в CreateWindow(), должен иметь сначала WM_NCCREATE, а обычный WM_CREATE последний, что согласуется с документацией уведомления и ссылкой CreateWindowEx() (а также с тем, что вы описать).

Раймонд Чен также имеет некоторую интересную информацию о создании / уничтожении окон .

Это просто говорит о том, что даже кажущиеся простыми вещи могут усложняться, чем больше на них смотришь.

7 голосов
/ 20 декабря 2009

Вы ответили на свой вопрос. Я также вижу WM_GETMINMAXINFO в Windows XP SP3, затем WM_NCCREATE, WM_NCCALCSIZE и, наконец, WM_CREATE до того, как CreateWindowEx () даже вернул дескриптор создаваемого окна. Что за фигня '

Общий ответ заключается в том, что Microsoft некомпетентна в том, что касается упорядоченного создания и уничтожения объектов. Они неправильно используют Windows, COM и драйверы устройств. Всегда есть какая-то ловушка-22, где объект наполовину создан или наполовину разрушен, и для получения надежного продукта требуется какое-то обходное извилистое решение.

2 голосов
/ 06 марта 2011

Результаты экспериментов лучше, чем просто доверие к источнику, тем более что источник состоит из множества программистов, и никто не знает весь код. Это сказало:

Первое сообщение, которое я получаю, - 0x24 (WM_GETMINMAXINFO).

Можно ли предположить, что это всегда будет первое сообщение? Нет, поскольку изменение кода между версиями Windows и Microsoft не задокументировало сообщение, которое гарантированно будет первым полученным.

Итог: Не предполагайте, что WM_CREATE был вызван перед другим сообщением.

1 голос
/ 20 ноября 2009

Вы можете использовать spy ++, который поставляется с visual studio, чтобы увидеть, какие сообщения генерируются при запуске приложения или окна.

...