Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
04-09-2015_19-17-13 / Конспект лекций.doc
Скачиваний:
98
Добавлен:
01.03.2016
Размер:
1.31 Mб
Скачать

17.5 Класс окна. Регистрация и его характеристики

Под классом окна подразумевается совокупность присущих ему характеристик, таких как стиль его границ, форм курсора, пиктограмм, цвета фона, наличия меню, адреса оконной процедуры, обрабатывающей сообщения этого окна. Класс окна можно впоследствии использовать для создания окон приложения функцией CreateWindow(). Характеристики окна описываются с помощью специальной структуры WNDCLASS.

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

В первом выполнимом предложении этой функции

if (hPrevInstance==NULL) Register(hInstance);

осуществляется вызов подпрограммы Register() в том случае, если дескриптор предыдущего экземпляра приложения равен нулю и, следовательно, данный экземпляр является первым и пока единственным. Функция Register() выполняет регистрацию класса главного окна нашего приложения, и поскольку при повторных запусках приложения основные характеристики окна, описанные в его классе, не изменяются, то и регистрировать в Windows класс окна требуется только один раз, при запуске первого экземпляра. Все это, конечно, имеет значение, только если данное приложение действительно будет эксплуатироваться в многозадачном режиме, когда одновременно выполняются несколько его экземпляров, что для прикладных задач бывает довольно редко; к тому же, даже если и попытаться повторно зарегистрировать уже зарегистрированный класс, ничего плохого не произойдет. Эта проверка также не имеет смысла в 32-разрядных приложениях, т. к. там дескриптор предыдущего экземпляра hPrevInstance всегда равен 0 и разделить таким образом первый и последующие экземпляры нельзя. Однако в технической документации по 16-битовым приложениям Windows рекомендуется регистрировать класс окна так, как это сделано в нашей программе.

Действия по регистрации класса окна мы вынесли для наглядности в отдельную функцию Register(). В ней объявляется и заполняется структура типа WNDCLASS, служащая для описания характеристик класса регистрируемого окна, а затем вызывается функция Windows RegisterClass(), которая и выполняет регистрацию данного класса.

Структура WNDCLASS, определенная в файле windows.h, содержит ряд членов, задающих ряд наиболее общих характеристик окна:

typedef struct tagWNDCLASS { /* wc */

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

WNDPROC lpfnWndProc; // Имя оконной функции

int cbClsExtra; // Число байтов дополнит. инф-ции о классе

int cbWndExtra; // Число байтов дополнит. инф-ции об окне

HINSTANCE hInstance; // Дескриптор приложения

HICON hIcon; // Дескриптор пиктограммы приложения

HCURSOR hCursor; // Дескриптор курсора приложения

HBRUSH hbrBackground; // Дескриптор кисти для фона окна

LPCSTR lpszMenuName; // Указатель на строку с именем окна

LPCSTR lpszClassName; // Указатель на строку с именем окна

} WNDCLASS; // Новое имя типа данной структуры

В такой простой программе, как наша, нет необходимости определять все члены этой структуры; для упрощения мы сначала обнуляем всю структуру командой

memset(&wc, 0, sizeof(wc)),

которая записывает, начиная с адреса &wc, нули в количестве sizeof(wc) штук, а затем задаем значения только интересующим нас членам.

Наиболее важными для дальнейшего функционирования программы являются три поля: hInstance, где хранится дескриптор данного приложения, lpszClassName, куда заносится произвольное имя, присвоенное нами окнам данного класса (у нас это окно единственное) и lpfnWndProc – адрес оконной функции. Именно с помощью структуры WNDCLASS Windows, обслуживая нашу программу, определяет адрес оконной функции, которую она должна вызывать при поступлении в окно сообщений. Поля lpszClassName и lpszMenuName мы заполняем из глобальных переменных, а значение дескриптора приложения поступает в функцию Register() через ее аргумент hInst. В поле lpszMenuName записывается указатель на ASCIIZ-строку с именем меню. Если меню не используется, то в поле записывается значение NULL. Поле lpszClassName содержит указатель на ASCIIZ-строку с присвоенным данному классу уникальным именем.

Менее важными в принципиальном плане, но существенными для разумного поведения приложения являются поля hIcon, hCursor и hbrBackground, куда следует записать дескрипторы пиктограммы приложения, его курсора и цвета фона (точнее, дескриптора цвета кисти, которая используется для закраски фоновой области окна). Кисть представляет собой ресурс в виде шаблона пикселов, которым закрашивается некоторый объект, в данном случае – фон окна приложения некоторого класса. Для получения такого дескриптора необходимо использовать функцию GetStockObject(). В качестве параметра ей передается имя нужной кисти. В файле wingdi.h содержатся символические имена констант, определяющих стандартные кисти.

Пиктограмма и курсор относятся к ресурсам Windows, которые обычно загружаются из специально созданного файла ресурсов с помощью функции Windows LoadCursor() и LoadIcon(). Символические имена констант, обозначающих стандартные курсоры и значки, содержатся в файле winuser.h. В качестве первого аргумента этих функций указывается дескриптор приложения, в котором хранится требуемый ресурс, а в качестве второго – имя ресурса. Однако можно обойтись и встроенными ресурсами Windows. Для этого в качестве первого аргумента этих функций указывается NULL (обычно NULL на месте дескриптора приложения обозначает саму систему Windows); второй аргумент надо выбрать из списка встроенных ресурсов Windows.

Цвет фона окна определяется дескриптором кисти, записанным в структуру WNDCLASS. Кисти можно придать любой цвет и даже фактуру, но проще всего воспользоваться одной из “встроенных” кистей, хранящихся в Windows, для этого следует воспользоваться функцией GetStockBrush(), в качестве единственного аргумента которой указывается константа, характеризующая цвет кисти.

Функция RegisterClass() требует в качестве аргумента адрес структурной переменной типа WNDCLASS, поэтому предложение вызова этой функции выглядит следующим образом:

RegisterClass(&wc);

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

Зарегистрировав класс окна, можно приступить к созданию и показу окна.

Соседние файлы в папке 04-09-2015_19-17-13