Изменение размеров, положения или состояния окна
Обычно при перемещении (в X, Y или Z направлении), изменении размеров окна или при изменении его состояния, помимо WM_SIZE и WM_MOVE Вы будете получать сообщения WM_WINDOWPOSCHANGING и WM_WINDOWPOSCHANGED. При этом все сообщения посылются функцией SetWindowPos(...) (или эквивалентной) в следующем порядке: WM_WINDOWPOSCHANGING 0 &WINDOWPOS cообщение указывает на то, что положение или состояние окна изменяется. Параметр lParam содержит указатель на структуру WINDOWPOS, описывающую положение окна и выполняемую операцию. Изменив соответствующие поля структуры можно изменить положение и размеры окна или повлиять на выполняемые действия. <сообщения активации окна(или всего приложения)> если окно просто активируется, то обычно следующее сообщение WM_WINDOWPOSCHANGED, завершающее всю цепочку, без всех рассматриваемых нами промежуточных сообщений, применяемых при изменении размеров или положения. WM_GETMINMAXINFO 0 &MINMAXINFO проверка новых размеров окна WM_NCCALCSIZE flag &NCCALCSIZE_PARAMS определение размера внутренней области WM_NCPAINT 0 0 отображение внешней области окна WM_ERASEBKGND hDC 0 очистка фона окна WM_WINDOWPOSCHANGED 0 &WINDOWPOS состояние окна изменено. Параметр lParam является указателем на структуру WINDOWPOS, содержащую данные о положении и размерах окна. Сообщения WM_WINDOWPOSCHANGING... WM_WINDOWPOSCHANGED часто не содержат между собой никаких иных сообщений, если состояние, размер и положение не изменились. (Часто это бывает, если окно активируется в ответ на “щелчок мышкой”). WM_MOVE 0 y & x WM_SIZE type height & width Эти сообщения информируют о новом положении и размерах окна. Они посылаются при соответствующих изменениях процедурой DefWindowProc() при обработке сообщения WM_WINDOWPOSCHANGED. Хотя в документации указано, что можно несколько ускорить работу, перехватывая вместо WM_MOVE и WM_SIZE сообщение WM_WINDOWPOSCHANGED и не вызывая при этом DefWindowProc(), но использовать этот прием нужно очень осторожно - так как сообщения WM_SIZE и WM_MOVE используются MDI окнами.
Рассмотренная нами цепочка сообщений порождается функцией SetWindowPos (или эквивалентной) и эти сообщения непосредственно передаются окну, а не посылаются. WM_PAINT 0 0 рисование внутренней области окна. В результате выполненной операции окно (или его часть), как правило, маркируется как неверное, что приводит к перерисовке окна. Сообщение WM_PAINT извлекается из очереди сообщений и может обрабатываться с некоторой задержкой после изменения размеров, положения или состояния окна. Обновление окна
После вызова ShowWindow() в WinMain() обычно следует процедура UpdateWindow(). Эта процедура проверяет наличие неверных прямоугольников и, если они есть, передает сообщение WM_PAINT (не ставит в очередь, а вызывает обработку этого сообщения). Обработка UpdateWindow(): WM_PAINT 0 0 Нарисовать внутреннюю область окна. Если для получения хендла контекста устройства используется функция BeginPaint(), то она может передавать сообщение WM_ERASEBKGND для очистки фона в неверном прямоугольнике (если при его создании было указано, что фон должен быть восстановлен). WM_ERASEBKGND hDC 0 Обрабатывая это сообщение, мы должны закрасить фон окна, используя переданный нам хендл контекста устройства, или вызвать обработку по умолчанию. Уничтожение окна
Для уничтожения окна надо вызвать функцию DestroyWindow(), которая выполнит требуемые действия по закрытию окна. Причем при этом посылаются: <сообщения деактивации (если надо)>
Иногда бывает так, что сообщения деактивации окна не поступают, происходит деактивация приложения и уничтожение окна; WM_DESTROY 0 0 Уничтожение внутренней области окна. WM_NCDESTROY 0 0 Уничтожение внешней области окна. Сообщения WM_DESTROY и WM_NCDESTROY являются последними сообщениями, получаемыми окном. После WM_NCDESTROY окно не получит ни одного сообщения, поэтому Вы можете смело разрушать все созданные для окна структуры данных. Сообщение WM_DESTROY удобно применять для уничтожения всех объектов, связянных с данным окном, в том числе и дочерних окон. Внимание: во время обработки сообщений WM_DESTROY и WM_NCDESTROY нельзя активировать каких-либо дочерних окон. (В том числе нельзя применять функцию MessageBox, передавая ей хендл уничтожаемого окна в качестве родительского) - это приведет к появлению дополнительных сообщений, направленных уничтожаемому окну, и, в конечном результате, к ошибке “General protection fault...” Если Вы хотите получить подтверждение перед закрытием окна, то Вы должны использовать сообщение WM_CLOSE. Функция DefWindowProc, обрабатывая это сообщение, вызывает функцию DestroyWindow. Вы можете легко вставить собственные средства для обработки сообщения WM_CLOSE, и вызывать DestroyWindow или процедуру по умолчанию только при положительном ответе на запрос. Сообщение WM_CLOSE лучше посылать, а не передавать. Событие WM_CLOSE используется самой средой, причем обычно предваряется последовательностью сообщений, приводящей к закрытию окна. Например такой: активация системного меню — выбор пункта ‘Close’ — завершение меню — посылка WM_SYSCOMMAND с параметром SC_CLOSE — посылка WM_CLOSE — уничтожение окна. Завершение работы Windows
Существует еще два сообщения, которое могут привести к закрытию окна: WM_QUERYENDSESSION 0 0 Это сообщение информирует о том, что Windows заканчивает работу когда приложение активно. Оно посылается ко всем запущеным приложениям. Если все возвращают TRUE, то Windows завершает работу. Обрабатывая это сообщение, Вы должны вернуть TRUE, если Ваше приложение может быть завершено, или FALSE в противном случае. При этом Windows продолжит нормальную работу. WM_ENDSESSION TRUE/FALSE 0 Это сообщение посылается активному приложению, если оно ответило TRUE на сообщение WM_QUERYENDSESSION. Флаг в параметре ‘wPar’ равный TRUE указывает, что работа Windows может завершиться сразу после обработки этого сообщения. Вы не обязаны уничтожать окно и посылать себе WM_QUIT для завершения работы, если завершается работа всего Windows.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|