Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
A05_API.doc
Скачиваний:
5
Добавлен:
12.11.2019
Размер:
1.3 Mб
Скачать

If (!RegisterClassEx(&wc))

{

MessageBox(NULL, "Класс окна не зарегистрирован", "Ошибка", MB_OK);

return 0;

};

// Создаем основное окно приложения

hMainWnd = CreateWindow(

szClassName,

"Да здравствует приложение!",

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT,

0,

CW_USEDEFAULT,

0,

(HWND)NULL,

(HMENU)NULL,

(HINSTANCE)hInstance,

NULL

);

If (!hMainWnd)

{

MessageBox(NULL, "Главное окно не создано", "Ошибка", MB_OK);

return 0;

};

// Показываем созданное окно

ShowWindow(hMainWnd, nCmdShow);

// Выполняем цикл обработки сообщений до закрытия приложения

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

};

return msg.wParam;

}

//---------------------------------------------------------------------------

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

HDC hDC;

PAINTSTRUCT ps;

RECT rect;

switch (uMsg)

{

case WM_PAINT:

hDC = BeginPaint(hWnd, &ps);

GetClientRect(hWnd,&rect);

DrawText(hDC, "Hello World!", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);

EndPaint(hWnd, &ps);

break;

case WM_CLOSE:

DestroyWindow(hWnd);

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default: return DefWindowProc(hWnd, uMsg, wParam, lParam);

};

return 0;

}

После компиляции и запуска программы на экране появтся окно, показанное на рис. 5.3.

Простая программа для Windows

Рис. 5.3

Обсудим теперь подробно содержание программы.

В программе имеется две функции: WinMain и WndProc. WinMain – это точка входа в программу. WndProc – это оконная процедура для главного окна программы. Оконная процедура инкапсулирует код, отвечающий за ввод информации, обычно осуществляемый при помощи клавиатуры или мыши, а также – за вывод информации на экран.

В программе отсутствуют инструкции для непосредственного вызова WndProc, т.к. оконная процедура вызывается только из Windows. Однако в WinMain имеется ссылка на WndProc (адрес оконной процедуры присваивается полю wc.lpfnWndProc), поэтому прототип функции WndProc объявлен в самом начале программного файла, еще до описания функции WinMain.

Обратим внимание на идентификаторы, написанные полностью прописными буквами. Эти идентификаторы задаются в заголовочных файлах Windows. Некоторые из них содержат двух- или трехбуквенный префикс, завершаемый символом подчеркивания, например, CS_HREDRAW, IDI_APPLICATION, IDC_ARROW, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT. Это просто числовые константы. Некоторые из этих категорий приведены в таблице 5.2.

Таблица 5.2. Префиксы для числовых констант

Префикс

Категория

CS_

Опция стиля класса

CW_

Опция создания окна

DT_

Опция рисования окна

IDC_

Идентификатор предопределенного курсора

IDI_

Идентификатор предопределенной иконки

WM_

Сообщение окна

WS_

Стиль окна

Также следует обратить внимание на типы данных, специфичные для системы Windows. Некоторые из них были приведены в таблице 5.1.

5.3.3. Регистрация класса окна. Сразу после входа в функцию WinMain создается и регистрируется класс главного окна приложения. Для этого необходимо заполнить структуру типа WNDCLASSEX, а затем передать адрес этой структуры в виде аргумента функции RegisterClassEx.

Структура WNDCLASSEX имеет двенадцать полей:

typedef struct tagWNDCLASSEX

{

UINT cbSize; // размер данной структуры в байтах

UINT style; // стиль класса окна

WNDPROC lpfnWndProc; // указатель на функцию окна (оконную процедуру)

int cbClsExtra; // число дополнительных байтов, которые дожны быть

// распределены в конце структуры класса

int cbWndExtra; // число дополнительных байтов, которые дожны быть

// распределены вслед за экземпляром окна

HINSTANCE hInstance; // дескриптор экземпляра приложения, в котором находится

// оконная процедура для этого класса

HICON hIcon; // дескриптор пиктограммы

HCURSOR hCursor; // дескриптор курсора

HBRUSH hbrBackground; // дексриптор кисти, используемой для закраски фона окна

LPCTSTR lpszMenuName; // указатель на строку, содержащую имя меню, применяемого

// по умолчанию для этого класса

LPCTSTR lpszClassName; // указатель на строку, содержащую имя класса окна

HICON hIconSm; // дескриптор малой пиктограммы

} WNDCLASSEX;

Рассмотрим назначение полей структуры WNDCLASSEX.

Значение первого поля, cbSize, должно быть равно длине структуры.

Второе поле, style, может содержать в своем значении один или несколько стилей, наиболее употребительные стили перечисленны в таблице 5.3.

Таблица 5.3. Стили класса окна

Стиль

Описание

CS_GLOBALCLASS

Создать класс, доступный всем приложениям. Обычно этот стиль применяется для создания определяемых пользователем элементов управления в DLL

CS_HREDRAW

Перерисовывать все окно, если изменен размер по горизонтали

CS_NOCLOSE

Запретить команду Close в системном меню

CS_OWNDC

Выделить уникальный контекст устройства для каждого окна, созданного при помощи этого класса

CS_VREDRAW

Перерисовывать все окно, если изменен размер по вертикали

В заголовочных файлах Windows идентификаторы, начинающиеся с префикса CS_, задаются в виде 32-разрядной константы, в которой только один разряд установлен в единичное состояние. Например, константа CS_VREDRAW задана как 00001, а CS_HREDRAW – как 00002. Подобные конмогут объединяться с помощью операции ИЛИ языка С++.

В рассматриваемой программе используется комбинация стилей CS_VREDRAW | CS_HREDRAW. Это означает, что все окна этого класса должны целиком перерисовываться при изменении как горизонтального, так и вертикального размеров окна. Если попробовать изменить размеры окна «Простое приложение для Windows», то можно увидеть, что строка текста «Для завершения закройте окно» переместится в новый центр окна. Механизм уведомления оконной процедуры об изменении размеров окна будет рассмотрен позже.

Третье поле, lpfnWndProc, содержит адрес оконной процедуры (в нашей программе это – WndProc).

Четвертое cbClsExtra и пятое cbWndExtra поля используются крайне редко, а назначение шестого поля, hInstance, очевидно, поэтому их обсуждать не будем.

Седьмое поле, hIcon, содержит дескриптор пиктограммы, которая предназначена для этого класса окна. Значение hIcon обычно получают вызовом функции LoadIcon, которая имеет следующий прототип:

HICON LoadIcon (HINSTANCE hInstance, LPCTSTR lpIconName).

Эта функция загружает ресурс пиктограммы, заданной параметром lpIconName, из экземпляра приложения, указанного параметром hInstance. Функцию можно использовать также для загрузки одной из системных пиктограмм, если передать первому аргументу значение NULL. В этом случае второй аргумент должен содержать константу, идентификатор которой начинается с префикса IDI_ («идентификатор значка» - ID for icon). Возможные значения второго аргумента для системных пиктограмм приведены в таблице 5.4.

Таблица 5.4. Идентификаторы системных пиктограмм

Значение

Описание

IDI_APPLICATION

Пиктограмма приложения по умолчанию

IDI_ASTERISK

Тог же, что и IDI_INFORMATION

IDI_ERROR

Пиктограмма в виде белого креста на фоне красного круга. Используется в серьезны предупреждающих сообщениях

IDI_EXCLAMATION

Тог же, что и IDI_WARNING

IDI_HAND

Тог же, что и IDI_ERROR

IDI_INFORMATION

Пиктограмма «i», которая используется в информационных сообщениях

IDI_QUESTION

Пиктограмма «?»

IDI_WARNING

Пиктограмма «!», которая используется в предупреждающих сообщениях

IDI_WINLOGO

Логотип Windows

Восьмое поле, hCursor, содержит дескриптор курсора мыши, используемого приложением в клиентской области окна. Значение hCursor обычно получают с помощью вызова функции LoadCursor, имеющей следующий прототип:

HCURSOR LoadCursor (HINSTANCE hInstance, LPCTSTR lpCursorName).

Эта функция загружает ресурс курсора, заданный вторым параметром (lpCursorName), из экземпляра приложения, заданного первым параметром(hInstance).

Функцию можно также использовать для загрузки одного из системных курсоров, если передать первому аргументу значение NULL. Значение второго аргумента при этом выбирается из таблицы 5.5.

Таблица 5.5. Идентификаторы курсора

Значение

Описание

IDC_APPSTARTING

Стандартная стрелка и малые песочные часы

IDC_ARROW

Стандартная стрелка

IDC_CROSS

Перекрестье

IDC_HELP

Стрелка и вопросительный знак

IDC_IBEAM

Текстовый двутавр

IDC_NO

Перечеркнутый кружок

IDC_SIZEALL

Четырехконечная стрелка

IDC_SIZENESW

Двухконечная стрелка, указывающая на северо-восток и юго-запад

IDC_SIZENS

Двухконечная стрелка, указывающая на север и юг

IDC_SIZENWSE

Двухконечная стрелка, указывающая на северо-запад и юго-восток

IDC_SIZEWE

Двухконечная стрелка, указывающая на запад и восток

IDC_UPARROW

Вертикальная стрелка

IDC_WAIT

Песочные часы

Девятое поле, hbrBackground, содержит дескриптор кисти, используемой приложением для закраски фона и клиентской области окна. Кисть - (brush) – это графический объект, который представляет собой шаблон пикселов различных цветов, используемый для закрашивания области. В Windows имеется несколько стандартных кистей. Вызов функции GetStockObject с аргументом WHITE_BRUSH возвращает дескриптор белой кисти. Возвращаемое значение имеет тип HGDIOBJ, поэтому необходимо преобразование его к типу HBRUSH.

Десятое поле, lpszMenuName, указывает на строку, содержащую имя меню, применяемого по умолчанию для данного класса. Рассматриваемая программа не имеет меню, поэтому поле установлено в NULL.

Одиннадцатое поле, lpszClassName, указывет на строку, содержащую имя класса. Это имя должно использоваться в параметре lpClassName функции CreateWindow.

Двенадцатое поле, hIconSm, содержит дескриптор малой пиктограммы, которая предназначена для использования в строке заголовка окон, созданных при помощи этого класса. Размеры пиктограммы должны быть 16  16 пикселов. Если поле равно NULL, то система ищет ресурс пиктограммы, указанный полем hIcon, чтобы сформировать малую пиктограмму из него.

Итак, с заполнением структуры класса окна мы разобрались. Осталось зарегистрировать подготовленный класс, вызвав функцию RegisterClassEx, передав ей параметром структуру WNDCLASSEX5.

5.3.4. Создание окна. Если регистрация класса окна прошла успешно, то следующий этап – создание окна. Для этого вызывается функция CreateWindow, прототип которой приведен ниже:

HWND CreateWindow (

LPCTSTR lpClassName, // имя зарегистрированного класса

LPCTSTR lpWindowName, // имя окна

DWORD dwStyle, //стиль окна

int x, //горизонтальная позиция

int y, //вертикальная позиция

int nWidth, //ширина окна

int Height, //высота окна

HWND hWndParent, //дескриптор родительского окна

HMENU hMenu, // дескриптор меню или идентификатор элемента управления

HINSTANCE hInstance, //дескриптор экземпляра приложения

LPVOID lParam //указатель на данные, передаваемые в сообщении WM_CREATE

).

Рассматривая назначение параметров, не будем забывать, что функция CreateWindow позволяет создавать не только основное окно приложения, но и любые другие окна, включая окна стантартных классов, с помощью которых реализуются элементы управления Windows.

Первый параметр, lpClassName, - это указатель на строку, содержащую допустимое имя класса. Таким именем может быть либо имя класса, зарегистрированное ранее при помощи функции RegisterClassEx ли RegisterClass, либо имя одного из стандартных классов, перечисленных в таблице 5.6

Таблица 5.6. Стандартные классы окон

Класс

Описание

Префикс в обозначении стилей

BUTTON

Прямоугольное окно кнопки, группы, флажка, переключателя или пиктограммы

BS_

COMBOBOX

Элемент управления, объединяющий элементы LISTBOX и EDIT. В поле редактирования отображается выбранная строка из LISTBOX

CBS_

EDIT

Прямоугольное окно (окно редактирования), предназначенное для ввода текста с клавиатуры

ES_

LISTBOX

Прямоугольное окно со списком строк, из которого пользователь может выбрать любую строку

LBS_

MDICLIENT

Клиентское окно многодокументного интерфейса. Это окно получает сообщения, которые управляют дочерними окнами в MDI - приложении

RICHEDIT

Элемент управления Rich Edit версии 1.0. В дополнение к возможностям элемента EDIT позволяет редактировать текст с разными шрифтами и стилями

ES_

RICHEDITCLASS

Элемент управления Rich Edit версий 2.0, 3.0. Усовершенствованная версия элемента RICHEDIT с дополнительными возможностями

ES_

SCROLLBAR

Элемент управления линейкой прокрутки

SBS_

STATIC

Элемент управления статическим текстом. Применяется для размещения в окне текста или рамок

SS_

Второй параметр, lpWindowName, - это указатель на строку, содержащую имя окна. Место отбражения имени зависит от вида окна. Например, для главного окна приложения оно выводится как заголовок окна, а для окна стандартного класса BUTTON размещается по центру кнопки.

Третий параметр, dwStyle, позволяет указывать стиль окна, сотоящий из значений, указанных в таблице 5.7.

Таблица 5.7. Стили окна

Обозначение стиля

Описание

WS_BORDER

Создать окно с рамкой в виде тонкой линии

WS_CAPTION

Создать окно, которое имеет область заголовка (включает стиль WS_BORDER)

WS_CHILD

Создать дочернее окно. Окно этого стиля не может иметь полосу меню и не может иметь стиль WS_POPUP

WS_CLIPCHILDREN

Исключить перерисовку дочерних окон, принадлежащих данному родительскому окну

WS_CLIPSIBLINGS

Исключить перерисовку соседних дочерних окон при перерисовке данного дочернего окна

WS_DLGFRAME

Создать окно, имеющее рамку со стилем, типичным для диалоговых окон. Окно этого стиля не может иметь область заголовка

WS_GROUP

Считать данное окно первым в группе элементов управления (обычно группируются переключатели)

WS_HSCROLL

Создать окно с горизонтальной линейкой прокрутки

WS_MAXIMIZE

Создать окно, которое первоначально является развернутым

WS_MAXIMIZEBOX

Создать окно с кнопкой развертывания

WS_MINIMIZE

Создать окно, которое первоначально является свернутым

WS_MINIMIZEBOX

Создать окно с кнопкой свертывания

WS_OVERLAPPED

Создать перекрывающееся окно. Окно этого стиля имеет область заголовка и рамку

WS_OVERLAPPEDWINDOW

Сочетание стилей WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX и WS_MAXIMIZEBOX

WS_POPUP

Создать всплывающее окно. Этот стиль не может использоваться со стилем WS_CHILD

WS_POPUPWINDOW

Сочетание стилей WS_BORDER, WS_POPUP и WS_SYSMENU. Чтобы сделать системное окно видимым, необходимо добавить стиль WS_CAPTION

WS_SYSMENU

Создать окно с системным меню в области заголовка

WS_TABSTOP

Стиль указывает, что на окне может остановиться фокус ввода, перемещаемый при помощи клавиши TAB

WS_THICKFRAME

Создать окно с рамкой, которая позволяет изменять его размеры

WS_VISIBLE

Создать окно, которое сразу же является видимым

WS_VSCROLL

Создать окно с вертикальной линейкой прокрутки

В рассматриваемой программе используется стандартный стиль для главного окна приложения - WS_OVERLAPPEDWINDOW. Это обычное перекрывающееся окно с заголовком, системным меню, расположенным в левой части строки заголовка, кнопками для сворачивания , разворачивания и закрытия окна справа на строке заголовка и «толстой» рамкой, позволяющей изменять размеры окна.

Четвертый параметр, х, задает горизонтальную позицию левого верхнего угла окна. Для главного окна позиции x и y определяются в экранных координатах, а для дочерних окон и элементов управления координаты отсчитываются относительно левого верхнего угла родительского окна.

Если позиция х не важна, то можно установить значение CW_USEDEFAULT. В этом случае Windows использует значения x и y по умолчанию. Это означает, что система располагает следующие друг за другом перекрывающиеся окна, равномерно отступая по горизонтали и вертикали от левого верхнего угла экрана.

Пятый параметр, y, задает вертикальную позицию левого верхнего угла экрана. Если параметр х имеет значение CW_USEDEFAULT, то значение параметра y игнорируется.

Шестой параметр, nWidth, задает ширину окна в пикселах. Если ему присвоено значение CW_USEDEFAULT, то система будет использовать значения nWidth и nHight по умолчанию.

Седьмой параметр, nHight, задает высоту окна в пикселах. Если параметр nWidth установлен в CW_USEDEFAULT, то значение nHight игнорируется.

Восьмой параметр, nWndParent, в рассматриваемой программе имеет значение NULL, поскольку у главного окна программы отсутствует родительское окно. Заметим, что, если между двумя окнами существует связь типа родительское – дочернее, дочернее окно всегда появляется только на поверхности родительского.

Девятый параметр, hMenu, содержит дескриптор меню окна или идентификатор элемента управления. Интерпретация значения параметра зависит от вида окна.

Если приложение использует меню, определенное в классе окна (поле lpszMenuName в структуре WNDCLASSEX), то параметру hMenu необходимо присвоить значение NULL.

Если создаваемое окно относится к элементу управления, то параметру hMenu передается целочисленное значение, которое далее используется как идентификатор созданного элемента. Этот идентификатор, например, будет содержаться в сообщениях WM_COMMAND, поступающих от элемента управления.

Десятому параметру, hInstance, должен быть присвоен дескриптор экземпляра приложения, переданный программе в качестве аргумента функции WinMain.

Последний параметр, lParam, в рассматриваемом примере тоже имеет значение NULL. При необходимости он может быть использован в качестве указателя на дополнительные данные, передаваемые окну в момент его создания с помощью сообщения WM_CREATE.

Итак, функция CreateWindow вызвана. Отработав, она возвращает дескриптор созданного окна. Если по какой-то причине создать окно не удалось, то функция возвращает значение NULL. Поэтому рекомендуется проверять возвращаемое функцией значение и в случае неудачи выдавать соответствующее сообщение, используя уже знакомую функцию MessageBox.

Использование функции CreateWindowEx. Для создания окна вместо функции CreateWindow может быть вызвана функция CreateWindowEx, прототип которой приведен ниже:

HWND CreateWindowEx (

DWORD dwExStyle,

LPCTSTR lpClassName,

LPCTSTR lpWindowName,

DWORD dwStyle,

int x,

int y,

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]