- •Лабораторный практикум «Основы разработки приложений 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. Локализация программных продуктов
- •Индивидуальные задания лабораторного практикума
1. Структура приложения Windows Простейшая программа с главным окном
Пример 1-1 представляет собой простейшее работоспособное приложение Windows, выводящее на экран главное окно со строкой заголовка и стандартным набором управляющих кнопок (рис. 1.1). Пока это окно пустое; заполнять его различной информацией мы будем в последующих примерах.

Рис. 1.1. Вывод программы 1-1, запущенной с рабочего стола Windows
/*Пример 1-1. Простейшая программа с главным окном*/
/*Операторы препроцессора*/
#include <windows.h>//Два файла с определениями, макросами
#include <windowsx.h>//и прототипами функций Windows
/*Прототип используемойв программе функциипользователя*/
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
/*Главная функция WinMain*/
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int){
char szClassName[]="MainWindow";//Имя класса главного окна
char szTitle[]="Программа 1-1";//Заголовок окна
MSG msg;//Структура msg для получения сообщений Windows
WNDCLASS wc;//Структура wc для задания характеристик окна
/*Зарегистрируем класс главного окна*/
ZeroMemory(&wc,sizeof(wc));//Обнуление всех членов wc
wc.lpfnWndProc=WndProc;//Определяем оконную процедуру
wc.hInstance=hInst;//Дескриптор приложения
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);//Пиктограмма
wc.hCursor=LoadCursor(NULL,IDC_ARROW);//Курсор мыши
wc.hbrBackground=GetStockBrush(WHITE_BRUSH);//Белый фон
wc.lpszClassName=szClassName;//Имя класса окна
RegisterClass(&wc);//Собственно регистрация класса окна
/*Создадим главное окно и сделаем его видимым*/
HWND hwnd=CreateWindow(szClassName,//Класс окна
szTitle, WS_OVERLAPPEDWINDOW,//Заголовок, стиль окна
10,10,300,100, //Координаты, размеры
HWND_DESKTOP,NULL,//Родитель, меню
hInst,NULL);//Дескриптор приложения, параметры
ShowWindow(hwnd,SW_SHOWNORMAL);//Покажем окно
/*Организуем цикл обработки сообщений*/
while(GetMessage(&msg,NULL,0,0))//Получить сообщение,
DispatchMessage(&msg);//вызвать WndProc
return 0;//После выхода из цикла вернуться в Windows
}//Конец функции WinMain
/*Оконная функция WndProcглавного окна*/
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,
WPARAM wParam,LPARAM lParam){
switch(msg){//Переход по значению msg – номеру сообщения
case WM_DESTROY://При закрытии приложения пользователем
PostQuitMessage(0);//Завершим приложение
return 0;//Возврат в Windows
default://Остальные сообщения обработать по умолчанию
return(DefWindowProc(hwnd,msg,wParam,lParam));
}//Конец оператора switch
}//Конец функции WndProc
Структура программы
Программа 1-1 состоит из нескольких отчетливо выделенных блоков (разделов):
группы операторов препроцессора;
раздела прототипов используемых в программе прикладных функций;
главной функции WinMain();
оконной функции главного окна.
Директивы препроцессора #include служат для включения в исходный текст программы содержимого указанных в них файлов (в результате чего, между прочим, размер исходного текста может увеличиться во много раз). Эти файлы называют заголовочными, и они обычно имеют расширение .H. В нашем примере включаемые заголовочные файлы являются системными в том смысле, что они входят в систему программирования; в дальнейшем мы будем использовать и собственные заголовочные файлы. Поскольку заголовочные файлы подсоединяются к исходному тексту программы, очевидно, что они должны представлять собой текстовые файлы, состоящие из операторов, понимаемых компилятором языка программирования.
В заголовочных файлах хранится главным образом информация следующего вида:
вложенные директивы #include, с помощью которых в программу включаются дополнительные системные заголовочные файлы (winuser.h, wingdi.h, winnt.h и др.);
определения констант, используемых функциями Windows;
определения новых типов данных Windows;
прототипы функций Windows;
макросы разного рода.
Константы.В системе Windows используется огромное количество символических констант, определяющих режимы работы тех или иных программных средств или свойства создаваемых объектов. В нашем примере используется несколько таких констант. Так, константаWHITEBRUSH (равная0), характеризующая цвет окна, описана в файлеWINGDI.H; константаIDCARROW (равная39512), задающая форму курсора мыши в виде стрелки, описана в файлеWINUSER.H; в тот же файл входит определение константыSWSHOWNORMAL со значением 1,которая устанавливает режим отображения главного окна приложения (нормальный, т. е. тех размеров, которые заданы в программе). Эти заголовочные файлы вошли в состав исходного текста программы, поскольку мы включили в него файлWINDOWS.H.
Типы данных Windows.В языке С++ определены основные типы данных, позволяющие использовать в программах арифметические, логические и символьные переменные. К этим типам относятся, например,int, char, float, unsigned int и др. Типы С++ отображают, главным образом, физическую организацию данных. Так, типchar описывает целое число, содержащееся в байте, типint – целое число, занимающее четыре байта, типfloat – число с плавающей точкой, тоже требующее четыре байта, но записываемое в память в специальном, довольно сложном формате и т. д. Помимо этих стандартных типов языка С++, в системе Windows используется большое количество специфических типов Windows, которые отображают не физическую организацию данных, а их назначение. Так, типHINSTANCE описывает дескрипторы приложений, типHWND –дескрипторы окон, типHBRUSH – дескрипторы кистей, типыWPARAM иLPARAM – параметры некоторых функций, типLRESULT – возвращаемое некоторыми функциями значение и т. д. С точки зрения физической организации все эти типы одинаковы; в 32-разрядных приложениях они занимают четыре байта памяти и равнозначны типуC++ unsigned int. Однако использоваться они должны только для описания соответствующих объектов. Кисть, например, не может описываться типомHWND, а окно – типомHINSTANCE.
Прототипы.Как известно, в языке С++ для всех используемых в программе функций обязательно должны быть указаны их прототипы. Если программист вводит в программу какие-либо собственные, прикладные функции, то их прототипы обязательно должны быть включены либо в исходный текст программы, либо в заголовочный файл. В нашем примере имеется единственная прикладная функцияWndProc(); ее прототип определен в начале программы. Однако в приложениях Windows всегда используется большое число системных функций (например, в нашей программе вызываются функцииRegisterClass(),ShowWindow() и др.). Прототипы этих функций определяются в системных заголовочных файлах. Включение в программу файлаWINDOWS.H, а через него и целой группы дополнительных заголовочных файлов, избавляет нас от необходимости описывать в программе прототипы всех используемых системных функций.
Макросы.Наконец, важным элементом заголовочных файлов являются определения макросов – программных объектов, чрезвычайно широко используемых в Windows. Макросы вводятся с помощью директивы препроцессора#defineи в простейшем случае служат просто для определения символической константы:
#define WHITE_BRUSH 0 //Константа WHITE_BRUSH, равная 0
#define GRAY_BRUSH 2 //Константа GRAY_BRUSH, равная 2
Более типичны макросы с аргументами. Например, используемое в примере 1-1 обозначение GetStockBrush(), по своему виду напоминающее функцию Windows, в действительности является макросом, определенным в файлеWINDOWSX.H:
#define GetStockBrush(i) ((HBRUSH)GetStockObject(i))
Этот макрос служит для преобразования значения, возвращаемого функцией GetStockObject(), с помощью которой можно получить дескрипторы хранящихся на складе(stock) инструментов (кистей, перьев и шрифтов), в типHBRUSH.ФункцияGetStockObject(), в соответствии со своим прототипом, возвращает обобщенный дескрипторHGDIOBJ, в то время как дескрипторы инструментов, используемые в программе, должны иметь типы, соответствующие их смыслу:HBRUSH – для кистей,HPEN – для перьев и т. д. МакросыGetStockBrush(),GetStockPen() иGetStockFont() избавляют нас от необходимости преобразовывать значение, возвращаемое функциейGetStockObject(), в требуемый тип, как это пришлось бы делать при непосредственном использовании этой функции:
wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
Между прочим, из-за того, что обозначение GetStockBrush()является макросом, а не функцией Windows, его нельзя найти в интерактивном справочнике среды программирования. Для выяснения смысла этого обозначения следует обратиться к файлуWINDOWSX.H (или, в других случаях, к другим заголовочным файлам), найти в нем этот макрос и попытаться расшифровать его.
