Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный практикум «Основы разработки приложений Windows» книга 1.DOC
Скачиваний:
107
Добавлен:
10.05.2014
Размер:
721.41 Кб
Скачать

Оконная функция

Как было показано в предыдущем подразделе, оконная функция вызывается, как только в структуру 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 предусмотрена специальная функция DefWin­dow­Proc(), которая умеет правильно обрабатывать практически все сообщения 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(). Эта функция генерирует сообщение WindowsWMQUIT, поступающее в очередь сообщений приложения. Как уже отмечалось выше, функцияGet­Mes­sage(), обнаружив в очереди приложения сообщениеWM­QUIT, тут же завершается с возвратом значенияFALSE. Это приводит к разрыву циклаwhileобработки сообщений, выполнению последнего оператораreturnфункцииWinMain()и завершению программы.