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

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; в тот же файл входит определение константыSW­SHOW­NORMAL со значением 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.ФункцияGet­Stock­Ob­ject(), в соответствии со своим прототипом, возвращает обобщенный дескрипторHGDIOBJ, в то время как дескрипторы инструментов, используемые в программе, должны иметь типы, соответствующие их смыслу:HBRUSH – для кистей,HPEN – для перьев и т. д. МакросыGetStockBrush(),GetStockPen() иGet­Stock­Font() избавляют нас от необходимости преобразо­вы­вать значение, возвращаемое функциейGetStockObject(), в требуемый тип, как это пришлось бы делать при непосредственном использовании этой функции:

wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

Между прочим, из-за того, что обозначение GetStock­Brush()является макросом, а не функцией Windows, его нельзя найти в интерактивном справочнике среды программирования. Для выяснения смысла этого обозначения следует обратиться к файлуWINDOWSX.H (или, в других случаях, к другим заголовочным файлам), найти в нем этот макрос и попытаться расшифровать его.