- •Лабораторный практикум «Основы разработки приложений Windows» Книга 1
- •Часть 1. Теоретические сведения4
- •Часть 2. Лабораторный практикум95
- •Часть 1 Теоретические сведения
- •1. Структура приложения Windows Простейшая программа с главным окном
- •Структура программы
- •Главная функция WinMain()
- •Регистрация класса окна
- •Создание и показ окна
- •Сообщения Windows и цикл их обработки
- •Оконная функция
- •Макрос handle_msg и структурирование программы
- •2. Интерфейс графических устройств
- •Простая программа, использующая средства gdi
- •Обработка сообщений wmpaint
- •Контекст устройства
- •Использование графических инструментов
- •3. Ресурсы: меню Простая программа с меню
- •Файл ресурсов
- •Описание меню в файле ресурсов
- •Сообщение wmcommand
- •Программное создание меню
- •Плавающее меню
- •Инструментальная панель
- •Всплывающие подсказки
- •0,"Первая строка"
- •1,"Вторая строка"
- •2,"Третья строка"
- •4. Ресурсы: диалоговые окна
- •Простая программа с меню и диалогом
- •Описание диалога в файле ресурсов
- •Обслуживание модального диалога
- •Модальный диалог как главное окно приложения
- •Немодальный диалог
- •Список в диалоговом окне
- •Окно редактирования и статический элемент управления
- •Графика в диалоговом окне
- •Перекрашивание диалогового окна и его элементов
- •Часть 2 Лабораторный практикум Работы лабораторного практикума Работа 1. Вызов функций Windows
- •Работа 2. Главное окно приложения (пример 1-1 из настоящего пособия)
- •Работа 3. Вывод в главное окно приложения текста и фигур (пример 2-1 из настоящего пособия)
- •Работа 4.Вывод в главное окно приложения текста и фигур (индивидуальное задание а)
- •Работа 5. Меню и модальный диалог (пример 4-1 из настоящего пособия)
- •Работа 6.Меню (индивидуальное задание в)
- •Работа 7.Модальный диалог в качестве главного окна приложения (индивидуальное задание с)
- •Работа 8.Вывод графика в главное окно приложения (индивидуальное заданиеD)
- •Работа 9. Немодальный диалог
- •Работа 10. Диалог с окном редактирования
- •Работа 11. Программное создание меню
- •Работа 12. Плавающее меню
- •Работа 13. График в диалоговом окне
- •Работа 14. Инструментальная панель (tool bar)
- •Работа 15. Инструментальная панель со всплывающими подсказками (tool tips)
- •Работа 16. Пользовательские пиктограммы и курсоры
- •Работа 17. Локализация программных продуктов
- •Индивидуальные задания лабораторного практикума
Оконная функция
Как было показано в предыдущем подразделе, оконная функция вызывается, как только в структуру 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(). Эта функция генерирует сообщение WindowsWMQUIT, поступающее в очередь сообщений приложения. Как уже отмечалось выше, функцияGetMessage(), обнаружив в очереди приложения сообщениеWMQUIT, тут же завершается с возвратом значенияFALSE. Это приводит к разрыву циклаwhileобработки сообщений, выполнению последнего оператораreturnфункцииWinMain()и завершению программы.