Московский инженерно-физический институт

Вид материалаПрактикум

Содержание


1. структура приложения Windows Простейшая программа с главным окном
Структура программы
Типы данных Windows.
Подобный материал:
1   2   3   4   5   6   7   8   9   ...   24

1. структура приложения Windows

Простейшая программа с главным окном


Пример 1-1 представляет собой простейшее работоспособное приложение Windows, выводящее на экран главное окно со строкой заголовка и стандартным набором управляющих кнопок (рис. 1.1). Пока это окно пустое; заполнять его различной информацией мы будем в последующих примерах.



Рис. 1.1. Вывод программы 1-1, запущенной с рабочего стола Windows

/*Пример 1-1. Простейшая программа с главным окном*/

/*Операторы препроцессора*/

#include //Два файла с определениями, макросами

#include //и прототипами функций 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 используется огромное количество символических констант, определяющих режимы работы тех или иных программных средств или свойства создаваемых объектов. В нашем примере используется несколько таких констант. Так, константа WHITEBRUSH (равная 0), характеризующая цвет окна, описана в файле WINGDI.H; константа IDCARROW (равная 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 (или, в других случаях, к другим заголовочным файлам), найти в нем этот макрос и попытаться расшифровать его.