- •Лабораторный практикум «Основы разработки приложений 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. Локализация программных продуктов
- •Индивидуальные задания лабораторного практикума
Главная функция WinMain()
Запуская приложение, мы фактически передаем управление программам Windows, которые загружают в память нашу программу и вызывают из нее главную функцию, которая обязательно должна иметь имя WinMainи описательWINAPI. Вызывая функциюWinMain(), Windows передает ей четыре параметра.
Первый параметр, имеющий тип HINSTANCEи поступающий в локальную переменную, названную нами в примере 1-1 hInst, представляет собой дескриптор приложения. Он назначается приложению при его запуске системой Windows и служит для его идентификации. Многие функции Windows используют этот дескриптор в качестве входного параметра, поэтому его часто приходится сохранять в соответствующей глобальной переменной. В данной программе сохранениеhInstне требуется.
Второй параметр того же типа в старых, 16-разрядных приложениях, являлся дескриптором предыдущего запущенного экземпляра этого же приложения (если приложение одновременно выполнялось в нескольких экземплярах); в 32-разрядных приложениях он всегда имеет значение NULL и не используется.
Следующий параметр представляет собой указатель на строку, содержащую параметры командной строки запуска приложения, если при его запуске были указаны какие-либо параметры. Поскольку мы не предполагаем запускать наше приложение с параметрами, и этот аргумент функции WinMain()нам не нужен, в заголовке функции указан только его типLPSTR, а сам аргумент опущен.
Наконец, через последний параметр Windows передает нам свои рекомендации по режиму запуска приложения (стандартного размера, свернутое в значок или развернутое на весь экран). В дальнейшем мы сами зададим режим запуска, рекомендации Windows нас не интересуют, и последний аргумент в заголовке функции также опущен.
В типичном приложении Windows главная функция WinMain() должна выполнить по меньшей мере три важных действия:
Зарегистрироватьв системе Windows класс главного окна. Если помимо главного окна планируется выводить на экран внутренние, порожденные окна, то их классы также необходимо зарегистрировать.Windows выводит на экран и обслуживает только зарегистрированные окна.
Создатьглавное окно ипоказатьего на экране. Порожденные окна также необходимо создавать, хотя это можно сделать и в другом месте программы, например, в ответ на выбор пользователем того или иного пункта меню.
Организовать цикл обработки сообщений, поступающих в приложение. Вся дальнейшая жизнь приложения будет фактически состоять в бесконечном выполнении этого цикла и в обработке поступающих в приложение сообщений. Запущенное приложение Windows обычно функционирует до тех пор, пока пользователь не подаст команду его завершения с помощью системного меню или вводом команды <Alt>+<F4>. Эти действия приводят к завершению главной функции и удалению приложения из списка действующих задач.
Функция WinMain после своего завершения возвращает в Windows целочисленный результат (в нашем примере 0), который системой не анализируется и нас интересовать не будет.
Регистрация класса окна
Как уже отмечалось, для вывода на экран любого окна, в частности главного окна приложения, необходимо прежде всего зарегистрировать класс окна, в котором задаются некоторые характеристики, присущие всем окнам данного класса. Это действие выполняется в первой, инициализирующей части функции WinMain().
Действия по регистрации класса окна заключаются в заполнении структурной переменной типа WNDCLASS, служащей для описания характеристик класса регистрируемого окна, и вызове затем функции WindowsRegisterClass(), которая и выполняет регистрацию данного класса.
Структура WNDCLASS, определенная в файлеWINUSER.H, содержит ряд членов, задающих наиболее общие характеристики окна, такие, как имя оконной функции, цвет фона, формы курсора и пиктограммы и др.
При заполнении структурной переменной типа WNDCLASS необходимо обеспечить нулевое значение всех элементов, которым мыне присваиваемконкретные значения. Нулевое значение элемента структуры обозначает для Windows, что характеристики этого элемента должны устанавливаться по умолчанию. Это правило, кстати, характерно и для других структур, описывающих те или иные объекты Windows, например для структурыOPENFILENAME, служащей для вывода на экран стандартного диалога Windows “Открытие файла”, или структурыLOGFONT, позволяющей создать шрифт требуемого начертания. Поэтому, объявив структурную переменнуюwc, мы прежде всего обнуляем ее вызовом функции WindowsZeroMemory()
ZeroMemory(&wc,sizeof(wc));
которая записывает, начиная с адреса &wc, нули в количествеsizeof(wc)штук. Далее ряду элементов структуры присваиваются определенные значения.
Наиболее важными для дальнейшего функционирования программы являются три поля: hInstance, где хранится дескриптор данного приложения,lpszClassName, куда заносится произвольное имя, присвоенное нами окнам данного класса (у нас это окно единственное) иlpfnWndProc– имя оконной функции. Именно с помощью структурыWNDCLASSWindows, обслуживая нашу программу, определяет адрес оконной функции, которую она должна вызывать при поступлении в окно сообщений. ПолеlpszClassNameмы заполняем из переменнойszClassName, определенной нами в начале программы, а значение дескриптора приложения переносим из параметраhInstфункцииWinMain().
Менее важными в принципиальном плане, но существенными для разумного поведения приложения являются поля hIcon, hCursorиhbrBackground, куда следует записать дескрипторы пиктограммы, курсора и цветной кисти, которой закрашивается фон окна.
Курсор относится к ресурсам Windows; ресурсы обычно загружаются из специально созданного файла ресурсов с помощью соответствующих функций Windows, в частности LoadCursor(). В качестве первого аргумента этих функций указывается дескриптор приложения, в котором хранится требуемый ресурс, а в качестве второго – имя ресурса. Однако можно обойтись и встроенными ресурсами Windows. Для этого в качестве первого аргумента этих функций указываетсяNULL(обычноNULLна месте дескриптора приложения обозначает саму систему Windows); второй аргумент надо выбрать из списка встроенных ресурсов Windows.
Другим ресурсом Windows, указываемым в классе окна, является пиктограмма. Как и курсор, пиктограмма может быть нарисована программистом специально для данного приложения и храниться в файле ресурсов приложения или в отдельном файле с расширением .ICO; для учебных задач проще использовать одну из стандартных пиктограмм Windows. Символические константы, обозначающие те или иные ресурсы Windows (курсоры и пиктограммы) можно найти в интерактивном справочнике, в статьяхLoadCursorи LoadIcon.
Цвет фона окна определяется дескриптором кисти, записанным в структуру WNDCLASS. Проще всего воспользоваться одной из встроенных кистей, хранящихся на складе Windows, получив ее оттуда с помощью макросаGetStockBrush()или функцииGetStockObject().
Можно ли закрасить главное окно приложения каким-нибудь другим цветом, например зеленым или желтым? Можно, однако, таких кистей нет на складе, и их придется создавать заново. Для создания кисти служит функция CreateSolidBrush(), в качестве единственного параметра которой указывается требуемый цвет в виде комбинации трех чисел, характеризующих интенсивность красной, зеленой и синей составляющих цвета. Для упаковки этих трех чисел в одно 4-байтовое слово и преобразования полученного значения в типCOLORREF, требуемый функциейCreateSolidBrush(), служит макросRGB(). Таким образом, чтобы сделать главное окно приложения, например, бирюзовым, надо заполнить элементhbrBackground структурной переменной типаWNDCLASS следующим образом:
wc.hbrBackground=CreateSolidBrush(RGB(0,255,255));
Отметим еще назначение стилякласса окна (элементstyle структурыWNDCLASS), хотя в нашем примере эта переменная не используется. Стиль представляет собой комбинацию констант, определяющих некоторые характеристики всех окон, принадлежащих регистрируемому классу. Так, указание константыCSDBLCLKS позволяет программе реагировать на двойные щелчки мышью в области окна; константыCSVREDRAW иCSHREDRAW заставляют Windows перерисовывать окно заново при каждом изменении его размеров по горизонтали и вертикали, константаCSNOCLOSE запрещает закрытие окна пользователем и т. д. Если стилю назначается несколько констант одновременно, их необходимо сложить с помощью оператора побитового ИЛИ:
wc.style= CS_VREDRAW |CS_HREDRAW;
Функция RegisterClass()требует в качестве аргументаадресструктурной переменной типаWNDCLASS, поэтому предложение вызова этой функции выглядит следующим образом:
RegisterClass(&wc);
Зарегистрировав класс окна, можно приступить к созданию и показу окна.