Московский инженерно-физический институт
Вид материала | Практикум |
СодержаниеОконная функция LRESULT CALLBACK WndProc(HWND hwnd,UINT msg |
- Ю. С. Барсуков 1, А. Ю. Окунев 2 1 Московский инженерно-физический институт (государственный, 29.25kb.
- В. А. Курнаев Московский инженерно-физический институт (государственный университет),, 27.18kb.
- «Вегето-сосудистая дистония», 192.12kb.
- Перечен ь научных разделов и базовых вузов по научным разделам открытого конкурса, 247.02kb.
- Д. В. Гуцко Московский инженерно-физический институт (государственный университет), 34.47kb.
- В. А. Тумольский московский инженерно-физический институт (государственный университет), 27.44kb.
- К. С. Чистов Московский инженерно-физический институт (государственный университет), 24.11kb.
- Вдокладе рассматривается задача оценки рисков инвестиционных проектов электростанций, 29.4kb.
- Резюме Луценко Владимир Юрьевич, 22.32kb.
- Л. Ю. Грецкая московский инженерно-физический институт (государственный университет), 26.28kb.
Оконная функция
Как было показано в предыдущем подразделе, оконная функция вызывается, как только в структуру msg попадает очередное сообщение, извлеченное из входной очереди. Задача оконной функции – определить природу сообщения и обработать его соответствующим образом.
Из заголовка оконной функции
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,
WPARAM wParam,LPARAM lParam)
видно, что при активизации (функцией DispatchMessage()) она получает четыре параметра. Первый параметр (hwnd) – дескриптор окна, которому предназначено данное сообщение. Это тот самый дескриптор, который был получен нами как результат работы функции CreateWindow(). Теперь этот же дескриптор вернулся к нам из Windows в виде параметра оконной функции. Он, в частности, полезен в тех случаях, когда на базе одного класса создается несколько различающихся чем-то окон. Если класс один, то и оконная функция для всех этих окон одна; анализируя тогда параметр hwnd, программа может определить, в какое именно окно пришло сообщение. У нас окно одно, однако аргумент hwnd все же понадобится.
Второй параметр (msg) определяет код пришедшего сообщения. Поскольку сообщений много, оконная функция должна прежде всего проанализировать этот код и осуществить переход на фрагмент обработки соответствующего сообщения. В настоящем (не лучшем, как будет видно из дальнейшего) варианте программы анализ аргумента msg осуществляется с помощью конструкции switch-case.
Оконная функция должна обрабатывать все поступающие в нее сообщения, и ее текст должен быть приблизительно таким:
switch(msg) {
case WM_CREATE:
...//Обработка сообщения WM_CREATE
case WM_MOUSEMOVE:
...//Обработка сообщения WM_MOUSEMOVE
case WM_TIMER:
...//Обработка сообщения WM_TIMER
case WM_DESTROY:
...//Обработка сообщения WM_DESTROY
//и т. д. для всех возможных сообщений
}
Однако реально в любой программе, по существу, требуется обрабатывать далеко не все сообщения. Например, если программа управляется только мышью, в ней нет необходимости обрабатывать сообщения от клавиатуры; совсем не обязательно программа имеет дело с таймером и т. п. Надо еще иметь в виду, что приложение получает большое количество сообщений системного характера, например о перерисовке отдельных элементов окна, определении его размеров, изменении положения окна и т. д. Всеми этими сообщениями мы не интересуемся и, возможно, даже не умеем обрабатывать их должным образом. Для того, чтобы дать возможность программисту работать только с теми сообщениями, которые ему нужны, в Windows предусмотрена специальная функция DefWindowProc(), которая умеет правильно обрабатывать практически все сообщения Windows. Единственным сообщением, не входящим “в юрисдикцию” DefWindowProc(), является сообщение об уничтожении окна WMDESTROY. Поэтому в простейшем случае, когда мы вообще не предполагаем работать с сообщениями, оконная функция все же должна включать обработку сообщения WMDESTROY:
switch(msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return(DefWindowProc(hwnd,msg,wParam,lParam));
}
Такая оконная функция обеспечит обработку по умолчанию всех поступающих в главное окно сообщений. Остается выяснить, как возникает сообщение WMDESTROY и в чем должна заключаться его обработка.
Обычно приложения Windows завершают свою работу по команде пользователя. Он может щелкнуть по кнопке завершения в правом верхнем углу окна, дважды щелкнуть по маленькой пиктограмме в левом верхнем углу окна, вызвать системное меню одиночным щелчком по этой пиктограмме и выбрать пункт "Закрыть" или, наконец, ввести с клавиатуры команду Alt+F4. Во всех этих случаях Windows убирает с экрана окно приложения и посылает в приложение сообщение WMDESTROY (не в очередь приложения, а с непосредственным вызовом оконной функции).
В чем должна состоять обработка этого сообщения? В процессе своего выполнения программа могла использовать те или иные ресурсы Windows: создать кисти, перья или шрифты, установить таймеры, динамически выделить память и т. д. Перед завершением приложения эти ресурсы желательно освободить. Возможно также, что программа использовала какие-то средства, не связанные с Windows, которые перед завершением работы следует привести в порядок: закрыть открытые файлы, выключить включенную аппаратуру и т. д. Наконец, может потребоваться вывод на экран предупреждающего сообщения.
Выполнив все эти завершающие действия, программа должна вызвать функцию Windows PostQuitMessage(). Эта функция генерирует сообщение Windows WMQUIT, поступающее в очередь сообщений приложения. Как уже отмечалось выше, функция GetMessage(), обнаружив в очереди приложения сообщение WMQUIT, тут же завершается с возвратом значения FALSE. Это приводит к разрыву цикла while обработки сообщений, выполнению последнего оператора return функции WinMain() и завершению программы.