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

СОЗДАНИЕ ОКНА

Полноценная программа для Win32 должна содержать как минимум две функции:

Win Main – главная функция, в которой создается основное окно программы и запускается цикл обработки сообщений;

WndProc – оконная процедура, в которой обрабатываются сообщения для основного окна программы.

Каркас Windows-программы

WinMain(список аргументов)

{

Подготовить и зарегистрировать класс окна;

Создать экземпляр окна зарегистрированного класса;

Пока не произошло необходимое для выхода событие

{

Извлечь очередное сообщение из очереди;

Передать его через Windows оконной функции;

}

Возврат из программы;

}

WndProc(список аргументов)

{

Обработать полученное сообщение;

Возврат;

}

Архитектура управления событиями

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

Сообщение – это структура, содержащая следующие элементы:

– декскриптор окна, которому адресовано сообщение;

– код (номер) сообщения;

– дополнительную информацию, зависящую от кода сообщения.

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

Чтобы осуществлять диспетчеризацию сообщений ОС при своей загрузке создает в памяти глобальный объект, который называется системной очередью сообщений. Все сообщения помещаются в эту очередь. Windows периодически опрашивает эту очередь и посылает сообщение нужному окну, которое определяется при помощи дескриптора.

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

Путь следования сообщений:

Событие > Системная очередь сообщений > Очередь сообщений приложения.

Оконная процедура

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

Функция обратного вызова. Так называют функцию, которую вызывает сама ОС. Компилятор узнает функцию обратного вызова по спецификатору CALLBACK.

LRESULT CALLBACK Имя функции (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

LRESULT – тип возвращаемого значения;

hWnd – дескриптор окна;

uMsg – код сообщения;

wParam и lParam – параметры сообщения.

Каждый код сообщения – это уникальный символический идентификатор. Чаще всего приложение обрабатывает оконные сообщения, начинающиеся с префикса WM_. Сообщения от других элементов управления начинаются с префиксов:

BM_ – кнопки;

EM_ – текстовые поля;

LB_ – списки.

Оконный класс

Оконный класс (или класс окна) – это структура, определяющая основные характеристики окна, такие как стиль окна и ресурсы (пиктограмма, курсор, меню и кисть для закрашивания фона).

Кроме того, одно из полей структуры содержит адрес оконной процедуры, предназначенной для обработки сообщений.

Ссылка на оконный класс передается функции создания окна CreatWindow.

Использование класса окна позволяет создавать множество окон на основе одного и того же оконного класса. Например, все кнопки создаются на основе класса BUTTON. Аналогичные системные классы имеются и для других элементов управления, таких как, например, списки и поля редактирования. Все эти классы называются предопределенными или стандартными оконными классами.

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

Цикл обработки сообщений

Все сообщения, адресованные приложению, Windows записывает в очередь сообщений приложения. Извлекает сообщение из очереди функция GetMessage. Если очередное сообщение WM_QUIT, то выход из цикла и приложение завершает свою работу. Если не WM_QUIT, то сообщение передается функции DispatchMessage, которая возвращает сообщение обратно в Windows. Windows отправляет сообщение для его обработки соответствующей оконной процедуре, иными словами Windows вызывает соответствующую оконную процедуру. После возврата из оконной процедуры Windows передает управление оператору, который расположен после DispatchMessage.

Файл исходного текста программы

Идентификаторы, такие как CS_HREDRAW, IDI_APPLICATION, IDC_ARROW, WS_SYSMENU, CW_USEDEFAULT, это просто числовые константы. Префикс обозначает основную категорию, к которой принадлежит константа.

Префикс

Категория

CS_

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

CW_

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

DT_

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

IDC_

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

IDI_

Идентификатор предопределенной иконки (пиктограммы)

WM_

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

WS_

Стиль окна

Регистрация класса окна

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

UINT cbSize – размер структуры в байтах. Значение поля д.б. равно длине структуры WNDCLASSEX;

UINT style – стиль класса окна. Стили перечислены в таблице.

Стиль

Описание

CS_GLOBALCLASS

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

CS_HREDRAW

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

CS_NOCLOSE

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

CS_OWNDC

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

CS_VREDRAW

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

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

int cbClsExtra – число дополнительных байтов, которые д.б. распределены в конце структуры класса. Поле используется редко.

int cbWndExtra – число дополнительных байтов, которые д.б. распределены вслед за экземпляром окна. Поле используется редко.

HINSTANSE hInstance – дескриптор экземпляра приложения, в котором находится оконная процедура для этого класса.

HICON hIcon – дескриптор пиктограммы.

HKURSOR hCursor – дескриптор курсора.

HBRUSH hbrBackground – дескриптор кисти.

LPCTSTR lpszMenuName – указатель на строку, содержащую имя меню. Если программа не имеет меню, то поле устанавливается в NULL.

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

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

Создание окна

Если регистрация прошла успешно, то следующий этап – создание окна.

HWND CreateWindow (

LPCTSTR szWindowClass, имя зарегистрированного класса. Таким именем может быть либо имя класса, зарегистрированного при помощи функции RegisterClassEx, либо имя одного из предопределенных классов, перечисленных в таблице.

Класс

Описание

Префикс

BUTTON

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

BS_

COMBOBOX

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

CBS_

EDIT

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

ES_

LISTBOX

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

LBS_

MDICLIENT

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

равляют дочерними окнами в MDI-приложении

RICHEDIT

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

ES_

RICHEDIT_CLASS

Усовершенствованная версия RICHEDIT с дополни-

тельными возможностями

ES_

SCROLLBAR

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

SBS_

STATIC

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

SS_

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

DWORD dwStyle, стиль окна, состоящий из значений, указанных в таблице

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

Описание

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_ OVERLAPPED

Сочетание стилей WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MAXIMIZEBOX и 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

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

int x, горизонтальная позиция левого верхнего угла;

int y, вертикальная позиция левого верхнего угла;

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

int nWidth, ширина окна в пикселах;

int nHeight, высота окна в пикселах;

HWND hWndParent, дескриптор родительского окна. Если родительское окно отсутствует, то значение NULL.

HMENU hMenu, дескриптор меню окна или идентификатор элемента управления. Если используется меню, определенное в классе окна (поле lpszMenuName в структуре WNDCLASSEX) то присваивается NULL.

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

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

);

Функция создания окна возвращает дескриптор созданного окна (тип HWND).

Отображение окна на экране

Для отображения окна вызывается функция ShowWindow.

Прототип: ShowWindow(HWND hWnd, int nCmdShow).

HWND hWnd – дескриптор окна;

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

Значение

Описание

SW_HIDE

Скрыть окно

SW_MAXIMIZE

Развернуть окно

SW_MINIMIZE

Свернуть окно

SW_SHOW

Активизировать окно и показать в его текущих размерах и позиции

SW_SHOWMINNOACTIVE

Окно не выводится, а на панели задач появляются его имя и пиктограмма

Обработка сообщений

MSG msg;

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

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

Переменная msg – это структура типа MSG, которая определена в заголовочных файлах Windows следующим образом:

typedef struct tagMSG {

HWND hwnd; // декскриптор окна, которому адресовано сообщ.

UINT message; // номер (идентификатор) сообщения (от 0 до 1024)

WPARAM wParam; // параметр сообщения wParam

LPARAM lParam; // параметр сообщения lParam

DWORD time; // время отправки сообщения

POINT pt; // поз. курс. (в экр. коорд.) в момент отправки сообщ.

} MSG;

Интерпретация параметров wParam и lParam зависит от номера сообщения.

Тип данных POINT:

typedef struct tagPoint {

LONG x;

LONG y;

} POINT;

Извлечение очередного сообщения осуществляется с помощью функции

GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax), где

lpMsg – задает адрес структуры типа MSG;

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

wMsgFilterMin – указывает минимальный номер принимаемого сообщения. Обычно равен нулю;

wMsgFilterMax – задает максимальный номер принимаемого сообщения. Также обычно равен нулю.

Функция GetMessage возвращает TRUE при извлечении любого сообщения, кроме WM_QUIT (выход из цикла и приложение завершает работу).

Вызов функции TranslateMessage нужен только в приложениях, которые должны обрабатывать ввод данных с клавиатуры. Сначала система генерирует сообщения о виртуальных клавишах, например: сообщение WM_KEYDOWN – когда клавиша наживается, и сообщение WM_KEYUP – когда клавиша отпускается. В сообщении WM_KEYDOWN содержится также информация о скан-коде (код, идентифицирующий нажатую клавишу и зависящий от аппаратной платформы).

Функция TranslateMessage преобразует сообщения WM_KEYDOWN и WM_KEYUP в сообщение WM_CHAR, которое содержит код символа (wParam) в виде значения TCHAR. Сообщение WM_CHAR помещается в очередь, а на следующей интерпретации цикла функция GetMessage извлекает его для последующей обработки.

Функция DispatchMessage передает структуру MSG обратно в Windows. Windows отправляет сообщение для его обработки соответствующей оконной процедуре, вызывая ее как функцию обратного вызова.

Оконная процедура

Реальная работа приложения осуществляется в оконной процедуре (в нашем конкретном случае WndProc).

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

Четыре параметра идентичны первым четырем полям структуры MSG.

Обычно используется оператор switch для определения сообщения. Если сообщение обрабатывается, то оконная процедура обязана вернуть нулевое значение. Все необрабатываемые оконной процедурой сообщения передаются системной функции DefWindowProc и возвращается значение, которое возвращает функция DefWindowProc. Программист пишет код только для тех сообщений, которые нуждаются в нестандартной обработке.