Сообщение окна: Разное между WM_CREATE и WM_NCCREATE? - PullRequest
11 голосов
/ 09 июня 2011

Я попытался создать кнопку (дочернее окно) внутри сообщения WM_NCCREATE, и ее положение, казалось, было создано с учетом координат экрана, а не клиентских координат. Сначала я думал, что WM_CREATE и WM_NCCREATE предоставляют нам одинаковый дескриптор окна, но это не соответствует действительности. Поэтому, может ли кто-нибудь объяснить мне разницу между сообщениями WM_CREATE и WM_NCCREATE? Кроме того, каковы различия между дескриптором окна в WM_CREATE и WM_NCCREATE?

Ответы [ 4 ]

11 голосов
/ 09 июня 2011

Сообщения WM_NC предназначены для не клиентской области, то есть границы окна и заголовка.Для ваших нужд вы не заинтересованы в этих не клиентских сообщениях.

10 голосов
/ 09 июня 2011

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

WM_NCCREATE, следовательно, является сообщением, на которое вы должны ответить, если вы реализуете оконную процедуру по умолчанию, которая должна выполнить инициализацию до того, как пользовательское proc proc обработает сообщение WM_CREATE.WM_NCCREATE также ДОЛЖЕН быть передан соответствующему DefWindowProc, вероятно, до того, как вы выполните свою собственную обработку, поскольку некоторые аспекты окна более низкого уровня явно находятся в неинициализированном состоянии до обработки WM_NCCREATE.

Если вы пытаетесь гарантировать первый взглядобработка НЕ ​​является вашим соображением, тогда WM_CREATE - подходящее место для инициализации окна: все другие слои, которые могут быть настроены по времени с помощью WM_NCCREATE, были выполнены, и окно находится в стабильном состоянии по сравнению с не клиентскимметрики, положение экрана и т. д.

Или: если вы не знаете, почему вы должны использовать WM_NCCREATE вместо WM_CREATE, то вам не следует использовать WM_NCCREATE.

5 голосов
/ 09 июня 2011

За MSDN:

WM_NCCREATE:

Отправлено до сообщения WM_CREATE когда окно создается впервые.

Возвращаемое значение:

Если приложение обрабатывает это сообщение должно вернуть TRUE продолжить создание окна. Если приложение возвращает FALSE, CreateWindow или CreateWindowEx Функция вернет дескриптор NULL.

WM_CREATE:

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

Возвращаемое значение:

Если приложение обрабатывает это сообщение должно вернуть ноль продолжить создание окна. Если приложение возвращает -1, окно уничтожается и CreateWindowEx или Функция CreateWindow возвращает NULL ручка.

0 голосов
/ 09 июня 2011

Не уверен, почему вы создаете кнопку в WM_NCCREATE - потому что окно, на котором появится кнопка, еще не существует, отсюда (я полагаю) координаты destop.WM_NCCREATE отправляется вам, когда собираются создать «не-клиентские» области окна (не-клиентские области, такие как граница окна, строка заголовка и т. Д.)

Нужно ли поставитькнопка на не клиентской области?Если ответ «нет», то почему бы не создать кнопку внутри WM_CREATE.

Если вам нужно по какой-то причине создать кнопку внутри WM_NCCREATE, то почему бы не сохранить дескриптор окна, возвращенный вашим вызовом Createwindow ().Затем, внутри вашего обработчика сообщений WM_CREATE, возьмите дескриптор окна этой кнопки и выполните «MoveWindow (...)» с помощью окна приложения, координаты которого у вас теперь должны быть, когда вы находитесь в обработчике сообщений WM_CREATE.

Я полагаю, что один из параметров, которые вы можете передать в свой вызов CreateWindow (...), чтобы создать кнопку, позволяет вам указать флаг «SW _...», такой как «SW_HIDE», если память мне не изменяет.Поэтому создайте, но не показывайте кнопку в обработке WM_NCCREATE, если необходимо, а затем, когда WM_CREATE быстро появляется после этого, выполните команду MoveWindow (.... координаты окна, ...... SW_SHOW, ......)и т.д., чтобы расположить и сделать видимой кнопку.

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