Файл: 15. Основы разработки событийно-управляемых программ в среде Windows.pdf
Добавлен: 20.10.2018
Просмотров: 1201
Скачиваний: 5
Для описания оконного класса используется специальная структура
данных со стандартным именем WndClass. Эта структура имеет 10 полей,
которые ВСЕ необходимо заполнить, но, к счастью, многие из них
заполняются стандартно. Прежде всего, необходимо ввести переменную
данного типа, имеющую любое осмысленное имя, например – MyWndClass.
Каждое поле этой структуры имеет свое жестко заданное имя, которое
мнемонически определяет смысл данного поля. Порядок установки полей не
имеет значения. С практической точки зрения наиболее интересными
являются следующие поля:
поле с именем lpfnWndProc, определяющее адрес оконной функции,
связываемой с данным оконным классом:
MyWndClass.lpfnWndProc := @ имя_оконной_функции;
поле-указатель lpszClassName на текстовую строку с именем
создаваемого оконного класса:
MyWndClass.lpszClassName := ‟MyClass‟;
имя класса может быть практически любым, за исключением
нескольких стандартных зарезервированных имен;
поле-указатель lpszMenuName на текстовую строку с именем меню,
используемом в главном окне программы:
MyWndClass.lpszMenuName := „MyMenu‟;
если меню не используется, полю присваивается пустое значение nil
или NULL;
поле hCursor, определяющее тип используемого в приложении курсора;
подключение курсора может выполняться с помощью API-функции
LoadCursor:
MyWndClass.hCursor := LoadCursor (0, idc_Arrow);
здесь второй параметр вызова – это константа, определяющая один из
стандартных курсоров, а именно – обычную стрелку; кроме нее, можно
использовать, например, такие курсоры, как перекрестие (idc_Cross)
или песочные часы (idc_Wait);
поле hbrBackground определяет шаблон заполнения фона окна с
помощью инструмента рисования – кисти (Brush) и может
устанавливаться многими способами:
MyWndClass.hbrBackground := CreateSolidBrush(RGB(0,100,255));
MyWndClass.hbrBackground := HBrush(Color_Window
);
здесь RGB – системная функция, определяющая цвет кисти для
заполнения фона как комбинацию трех базовых составляющих цвета –
красного (Red), зеленого (Green) и синего (Blue); интенсивность
каждой составляющей задается целым числом от 0 до 255; например,
RGB(0, 0, 0) задает черную кисть, а RGB(255, 255, 255) – белую;
поле hIcon определяет пиктограмму окна при его сворачивании и
устанавливается с помощью вызова LoadIcon:
MyWndClass.hIcon := LoadIcon (0, idi_Application);
здесь константа idi_Application определяет стандартную пиктограмму
приложения.
Кроме перечисленных выше, необходимо установить следующие поля,
которые приводятся без комментариев в силу их редкого изменения:
MyWndClass.Style := cs_VRedraw OR cs_HRedraw OR cs_DblClks;
MyWndClass.cbClsExtra := 0;
MyWndClass.cbWndExtra := 0;
MyWndClass.hInstance := hInstance;
2. После задания всех 10 полей структуры WndClass ее надо
зарегистрировать в системе с помощью API-вызова RegisterClass с проверкой
результата регистрации:
if RegisterClass(MyWndClass) = 0 then Exit; // неудачная регистрация
необходимость проверки связана с тем, что иногда она может привести к
отрицательному результату, и в этом случае дальнейшая работа приложения
невозможна.
3. После успешной регистрации оконного класса можно создавать окна
данного класса. Как минимум, должно быть создано одно главное окно.
Создание одного окна выполняется с помощью одного вызова API–функции
CreateWindow. Этот вызов принимает 11 параметров (более поздняя версия –
уже 13). Эти параметры конкретизируют создаваемое на основе данного
класса окно. Важно понимать, что создание окна – это не отображение окна
на экране, а создание соответствующей информационной структуры с
основными параметрами окна. Если создание окна проходит успешно, то
вызов CreateWindow возвращает специальный описатель окна, так
называемый дескриптор. Для работы с дескриптором надо ввести
переменную системного типа HWnd. Многие последующие функции работы
с окнами требуют задания дескриптора как одного из параметров.
Что касается входных параметров вызова CreateWindow, то из 11
параметров наиболее важными являются первые 9:
первый параметр определяет имя оконного класса, на основе которого
создается данное окно; это имя чаще всего совпадает с именем,
заданным в качестве значения поля lpszClassName структуры оконного
класса;
второй параметр определяет текст в заголовке окна (если текст не
нужен, надо задать 0);
третий параметр задает стиль создаваемого окна; для этого
используется набор специальных стилевых констант, среди которых
чаще всего используются:
o
константа ws_Overlapped определяет стиль главного окна;
o
константа ws_Child определяет стиль дочернего окна, которое
обязательно имеет родительское окно, одинаковый с ним вид и
поведение; родителем может быть как главное окно, так и любое
ранее созданное дочернее окно; тем самым окна могут
образовывать вложенную иерархию;
o
константа ws_PopUp определяет еще одну разновидность
подчиненных окон, так называемые всплывающие окна, которые
также должны иметь родителя, но ведут себя немного по-
другому по сравнению с дочерними окнами; перечисленные
выше стили не должны использоваться совместно при создании
одного окна;
o
константа ws_Visible определяет видимость создаваемого окна;
o
константа Ws_Border определяет наличие рамки у окна;
o
константа Ws_Caption определяет наличие у окна заголовка;
o
константы ws_MaximizeBox и ws_MinimizeBox определяют,
имеет окно кнопки максимизации или минимизации;
при необходимости некоторые перечисленные выше стили можно
объединять вместе, используя логическую операцию ИЛИ (например –
OR):
WsVisible OR ws_Caption OR ws_Border
очевидно, что не все стили можно комбинировать вместе, например –
стили главного окна, дочернего и всплывающего противоречат друг
другу;
четвертый и пятый параметры определяют координаты левого верхнего
угла окна относительно клиентской части его родителя, а для главного
окна - относительно рабочего стола (клиентская часть окна образуется
за вычетом заголовка и рамки); координаты задаются в пикселах;
шестой и седьмой параметры определяют ширину и высоту
создаваемого окна в пикселах:
восьмой параметр определяет для создаваемого окна его родителя и
задается соответствующим дескриптором; отсюда видно, что порядок
создания окон должен быть вполне конкретным: сначала родитель,
потом только подчиненное окно; первое по порядку создаваемое окно
является главным, и для него восьмой параметр надо задать нулевым;
девятый параметр в основном используется для присваивания окнам
уникальных идентификаторов; использование этого параметра будет
объяснено позже, а пока будем считать его нулевым.
Пример программного кода, создающего два окна, может выглядеть так:
var MyMainWin, MyChildWin : HWnd;
MyMainWin := CreateWindow(„MyClass‟, „Это главное окно‟,
ws_OverlappedWindow, 100, 100, 400, 300, 0, 0, hInstance, nil);
MyChildWin := CreateWindow(„MyClass‟, „А это дочернее‟, ws_Child OR
ws_Visible OR ws_Caption OR ws_Border, 50, 50, 200, 100,
MyMainWin, 0, hInstance, nil);
4. После создания окон можно выполнить их отображение на экране. При
этом достаточно отобразить лишь главное окно, все подчиненные окна
отобразятся автоматически. Для отображения главного окна в целом и его
клиентской части используются два системных вызова:
ShowWindow (MyMainWin, cmdShow);
UpdateWindow (MyMainWin);
5. Последним шагом в главной программе является запуск цикла обработки
сообщений. В простейшем случае этот цикл реализуется двумя API
функциями:
while GetMessage (MyMessage, 0, 0, 0)
DispatchMessage (MyMessage);
Здесь параметр MyMessage - это переменная системного типа Msg,
используемая для хранения извлекаемого из очереди сообщения. Вызов
GetMessage извлекает из очереди очередное сообщение, а вызов
DispatchMessage передает это сообщение в оконную функцию на обработку.
Цикл while закончит свою работу, когда вызов GetMessage вернет значение 0,
а это произойдет в ответ на появление в очереди сообщений специального
сообщения wm_Quit, помещаемого в очередь в ответ на закрытие главного
окна приложения. Практически всегда перед вызовом DispatchMessage
выполняется вызов функции TranslateMessage, используемой для обработки
клавиатурных сообщений.