2009-11-16 2 views
7

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

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

+1

Этот вопрос не имеет смысла. Как вы отметили, первые сообщения не всегда одинаковы. В зависимости от того, создано ли окно видимым или нет, в WindowProoc может появиться целое количество сообщений, прежде чем CreateWindow вернется. какие сообщения и их порядок изменились между версиями окон. Все, что вам гарантировано, заключается в том, что WM_CREATE - и теперь WM_NCREATE - будет отправлен до возврата CreateWindow (Предполагая успешное создание окна). –

+3

Крис, почему комментарий вместо ответа? Кроме того, разве это не имеет никакого смысла? Я уверен, что 90% разработчиков Win32 поклялись, что WM_CREATE является первым полученным msg (и я был одним из них до 30 секунд назад). В конце концов, это то, что мы все читаем в наших учебниках. –

+0

Согласен Серж Вотье, я тоже думал об этом, пока не сделал небольшой тест. Это порядок всех моих сообщений WM до WM_CREATE: WM_GETMINMAXINFO, WM_NCCREATE, WM_NCCALCSIZE, WM_CREATE. – Kit10

ответ

6

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

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

+0

WM_GETMINMAXINFO - это первое сообщение для окна верхнего уровня. Для других окон это выглядит как WM_NCCREATE. –

13

WM_NCCREATE на самом деле very first message your window will receive, который поступит до WM_CREATE. Это связано с созданием неклиентской области (например, строка заголовка, системное меню и т. Д.), Следовательно, префикс NC.

WM_GETMINMAXINFO выслан before the window size/position is changed и может прибыть до WM_CREATE (см. Ниже).

Сообщение WM_CREATE отправлено до того, как возвращается CreateWindow(), поэтому вы можете гарантировать, что инициализация каждого окна была выполнена этой точкой. Ваше окно proc получит 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() (а также в соответствии с тем, что вы описать).

Раймонд Чен также имеет некоторые интересные information on window creation/destruction.

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

+0

Интересно, что WM_NCCREATE был представлен в Win95, что объясняет, почему он не был задокументирован в «Программе Windows» Петцольда, когда я впервые прочитал его в 1997 году. –

+2

WM_NCCREATE существует со времен Windows 1.0. Существует много того, что Петцольд никогда не пытался покрыть. –

+1

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

1

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

2

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

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

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

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

+1

Нет, эксперименты никогда не являются хорошей идеей. Эти вещи недокументированы по какой-то причине. Нет никакой гарантии, что 'WM_GETMINMAXINFO' будет * всегда * быть первым отправленным сообщением, независимо от того, какая версия Windows и конфигурация машины пользователя. Любое приложение, которое полагается на получение сообщений в определенном порядке, как это, принципиально нарушено. В документации указывается, что «WM_NCCREATE» - первое полученное сообщение. Вы должны выполнить всю свою инициализацию там: он будет работать каждый раз, независимо от того, в какой системе работает ваше приложение. Не переделывайте Windows. –