lect116-117.ppt
- Количество слайдов: 31
Лекции 16 – 17 Программирование с использованием Win 32 API: каркас приложения, создание окна и обработка событий
Библиотека Win 32 API – Application Program Interface Библиотека Win 32 API – библиотека, содержащая функции ОС Windows предназначенные для организации взаимодействия прикладных программ пользователя с сервисом, предоставляемым ОС Windows. В программу необходимо, как минимум, подключить библиотеку
Структура окна Заголовок окна Главное меню окна Рабочая область окна
Библиотека Win 32 API В библиотеке Win 32 API содержится описание довольно большого количества типов данных, большинство из которых создано с использованием директив #define или typedef. Эти типы данных могут переопределять системные типы данных языков С/C++ таких как int, long, char*, const char* и д. р. Также эти типы данных могут содержать объявления структур, предназначенных для описания каких-либо сложных объектов, посредством которых осуществляется взаимодействие с операционной системой.
Библиотека Win 32 API HANDLE Дескриптор некоторого ресурса, связанного с приложением (целое 32 -ух разрядное число) HWND Идентификатор окна (целое 32 -ух разрядное число) HDC Идентификатор контекста устройства (целое 32 -ух разрядное число) LONG Целое 32 -разрядное число со знаком LPSTR Указатель на С-строку (char *) NULL 0 INT Целое 32 -разрядное число со знаком UINT Целое 32 -разрядное число без знака WCHAR 16 -ти разрядный символ UNICODE BOOL Логический тип HBRUSH Дескриптор кисти HPEN Дескриптор пера HMENU Дескриптор меню LRESULT Значение типа long, возвращаемое системными вызовами
Архитектура, управляемая событиями В основе взаимодействия программы с внешним миром и с операционной системой лежит концепция сообщений. С точки зрения приложения, сообщение является уведомлением о том, что произошло некоторое событие, которое может требовать, а может и не требовать выполнения определенных действий. Это событие может быть следствием действий пользователя, например перемещения курсора или щелчка кнопкой мыши, изменения размеров окна или выбора пункта меню. Кроме того, событие может генерироваться приложением, а также операционной системой.
Архитектура, управляемая событиями Сообщение - это структура данных, содержащая следующие элементы: n дескриптор окна, которому адресовано сообщение; n код (номер) сообщения; n дополнительную информацию, зависящую от кода сообщения. Сообщения в Windows описываются с помощью структуры MSG: typedef struct tag. MSG { HWND hwnd; // Идентификатор окна-получателя UINT message; // Идентификатор сообщения WPARAM w. Param; // Дополнительная информация, смысл LPARAM l. Param; // которой зависит от типа сообщения DWORD time; // Время посылки сообщения POINT pt; // Местоположение указателя мыши } MSG;
Архитектура, управляемая событиями Сообщения от внешних источников, например от клавиатуры, адресуются в каждый конкретный момент времени только одному из работающих приложений, а именно - активному окну. Windows играет роль диспетчера сообщений. Для этого с момента старта операционная система создает в памяти глобальный объект, называемый системной очередью сообщений. Все сообщения, генерируемые как аппаратурой, так и приложениями, помещаются в эту очередь. Windows периодически опрашивает эту очередь и, если она не пуста, посылает очередное сообщение нужному адресату, определяемому при помощи дескриптора окна. Сообщения, получаемые приложением, могут поступать асинхронно из разных источников. Например, приложение может работать с системным таймером, посылающим ему сообщения с заданным интервалом, и одновременно оно должно быть готовым в любой момент получить любое сообщение от операционной системы. Чтобы не допустить потери сообщений, Windows одновременно с запуском приложения создает глобальный объект, называемый очередью сообщений приложения.
Каркас Win 32 приложения Основу программы в Win 32 составляет функция Win. Main, которая «заменяет» собой стандартную функцию main языков C и C++. Описание этой функции имеет следующий вид: int WINAPI Win. Main (HINSTANCE h. Instance, HINSTANCE h. Prev. Instance, LPSTR lp. Cmd. Line, int n. Cmd. Show) { … return Код_вовзрата; } В некоторых средах разработки вместо WINAPI пишут APIENTRY
Каркас Win 32 приложения Параметры функции Win. Main: n HINSTANCE h. Instance – идентификатор текущего приложения; n HINSTANCE h. Prev. Instance – идентификатор приложения, являющегося родительским для данного приложения; n LPTSTR lp. Cmd. Line – С-строка, содержащая параметры командной строки; n int n. Cmd. Show – код вида начального отображения окна. Возвращаемое значение функции Win. Main: целое число, интерпретируемое как код возврата. Обычно в качестве его значения указывается параметр сообщения закрытия приложения в виде: (int) msg. w. Param
Каркас Win 32 приложения НАЧАЛО Описание класса окна Регистрация класса окна Создание окна Отображение окна Ожидание, прием и обработка сообщения Это сообщение завершения Да КОНЕЦ
Каркас Win 32 приложения Для описания класса окна необходимо заполнить структуру типа WNDCLASSEX или WNDCLASS (старый вариант). typedef struct tag. WNDCLASSEXW { UINT cb. Size; UINT style; WNDPROC lpfn. Wnd. Proc; int cb. Cls. Extra; int cb. Wnd. Extra; HINSTANCE h. Instance; HICON h. Icon; HCURSOR h. Cursor; HBRUSH hbr. Background; LPCWSTR lpsz. Menu. Name; LPCWSTR lpsz. Class. Name; HICON h. Icon. Sm; } WNDCLASSEXW; //Размер структуры //Стиль окна //Адрес функции обработки сообщений //Размер дополнительной памяти в байтах под //структуру класса-окна (инициализируется 0) //Размер дополнительной памяти в байтах под //структуру окна (инициализируется 0) //Код приложения //Код идентификатора иконки приложения //Код идентификатора курсора //Код идентификатора кисти фона окна //Имя ресурса, описывающего меню программы //Имя класса окна //Код идентификатора иконки класса окна
Каркас Win 32 приложения После заполнения всех полей данной структуры класса окна необходимо зарегистрировать с помощью функции Register. Class. Ex() или Register. Class() (старый вариант). Прототип функции: ATOM Register. Class. Ex(CONST WNDCLASSEX *lpwcx ); В параметре в функцию передается адрес заполненной структуры типа WNDCLASSEX. Функция возвращает идентификатор зарегистрированного класса окна в случае успешного выполнения. В случае ошибки функция возвращает 0.
Каркас Win 32 приложения После успешной регистрации класса окна необходимо создать само окно. Это осуществляется с помощью функции Create. Window. Прототип функции: HWND Create. Window( LPCTSTR lp. Class. Name, //С-строка содержащая имя класса LPCTSTR lp. Window. Name, //C-строка содержащая имя окна DWORD dw. Style, //Стиль окна int x, //Позиция x на экране int y, //Позиция y на экране int n. Width, //Ширина окна (по оси X) int n. Height, //Высота окна (по оси Y) HWND h. Wnd. Parent, //Дескриптор родительского окна HMENU h. Menu, //Дескриптор главного меню HINSTANCE h. Instance, //Идентификатор приложения LPVOID lp. Param //Параметры сообщения WM_CREATE );
Каркас Win 32 приложения В случае успешного выполнения функция Create. Window возвращает дескриптор созданного окна. В случае ошибки функция возвращает NULL. Некоторые стили окна: WS_BORDER Создает окно с «неподвижной» границей WS_CAPTION Создает окно у которого есть заголовок WS_CHILD Создает дочернее окно (вложено в другое окно) WS_DISABLED Создает «запрещенное» окно, в него не передаются сообщения WS_DLGFRAME Создает диалоговое окно WS_HSCROLL Создает окно с горизонтальной полосой прокрутки WS_OVERLAPPED Создает окно с заголовком и «подвижной» границей WS_MAXIMIZE Создает окно изначально развернутое на весь экран WS_MINIMIZE Создает окно изначально свернутое WS_POPUP Создает «всплывающее» окно (в противоположность WS_CHILD) WS_VISIBLE Создает окно изначально видимое на экране WS_VSCROLL Создает окно с вертикальной полосой прокрутки
Каркас Win 32 приложения После того, как окно успешно создано, его необходимо отобразить используя функции Show. Window и Update. Window. Функция отображения окна: BOOL Show. Window(HWND h. Wnd, int n. Cmd. Show); Некоторые типы команд отображения окна: n SW_HIDE – скрыть окно и активизировать другое окно, n SW_MAXIMIZE – развернуть на весь экран, n SW_MINIMIZE – свернуть окно и активизировать предыдущее окно, n SW_RESTORE – восстановить изначальные размеры окна, n SW_SHOW – активизировать окно и отобразить его. Функция возвращает истину, если окно было изначально видимо, и ложь – если нет. Функция обновления окна: void Update. Window(HWND h. Wnd); Вызывает обновление (перерисовку) окна.
Каркас Win 32 приложения После создания и отображения окна необходимо организовать цикл получения и обработки сообщений. Для этих целей в Win 32 API используются следующие функции: n n n Get. Message – получение сообщения, Translate. Message – преобразует сообщения виртуальных клавиш в символьные сообщения, Dispatch. Message – вызывает обработчик сообщения.
Каркас Win 32 приложения Функция получения сообщения BOOL Get. Message( LPMSG lp. Msg, //Указатель на структуру MSG HWND h. Wnd, //Дескриптор окна UINT w. Msg. Filter. Min, //Минимальный номер отслеживаемых сообщений UINT w. Msg. Filter. Max //Максимальный номер отслеживаемых сообщений ); Если функция получает сообщение отлично от WM_QUIT, то возвращается не нулевое значение (истина).
Каркас Win 32 приложения Функция преобразования сообщения виртуальных клавиш в символьные сообщения BOOL Translate. Message(const MSG *lp. Msg ); Возвращает значение «истина» , если сообщение было успешно преобразовано. Если сообщение не преобразовано, то возвращает значение «ложь» Данная функция предназначена для создания сообщений WM_CHAR на основе сообщений WM_KEYDOWN и WM_KEYUP.
Каркас Win 32 приложения Функция обработки сообщения LRESULT Dispatch. Message(const MSG *lpmsg ); Функция вызывает функцию-обработчик сообщений для данного окна и возвращает результат обработки. Значение результата зависит от самой функцииобработчика, и как правило игнорируется.
Типовая функция Win. Main int WINAPI Win. Main (HINSTANCE h. Instance, HINSTANCE h. Prev. Instance, LPSTR lp. Cmd. Line, int n. Cmd. Show) { MSG msg; HWND hwnd; WNDCLASSEX wcx; //Заполнение полей структуры wcx if(!Register. Class. Ex(&wcx)) return FALSE; hwnd = Create. Window(/*параметры*/); if(!hwnd) return FALSE; Show. Window(h. Wnd, n. Cmd. Show); Update. Window(h. Wnd); while(Get. Message(&msg, NULL, 0, 0)){ Translate. Message(&msg); Dispatch. Message(&msg); } return (int)msg. w. Param; }
Функция-обработчик сообщений Прототип функции: LRESULT CALLBACK Wnd. Proc( HWND hwnd, //Дескриптор окна UINT message, //Код сообщения WPARAM w. Param, //Первый параметр сообщения LPARAM l. Param //Второй параметр сообщения ); Тип WPARAM – unsigned int Тип LPARAM – long
Типовой алгоритм функции Wnd. Proc LRESULT CALLBACK Wnd. Proc(HWND hwnd, UINT message, WPARAM w. Param, LPARAM l. Param) { switch(message){ case WM_DESTROY: Post. Quit. Message(0); break; case СОБЫТИЕ_1: //Обработка события 1 break; case СОБЫТИЕ_2: //Обработка события 1 break; … default: return Def. Window. Proc(hwnd, message, w. Param, l. Param); } return 0; }
Некоторые сообщения WM_CREATE Событие создания окна WM_DESTROY Событие уничтожения окна WM_MOVE Событие перемещения окна WM_SIZE Событие изменения размеров окна WM_PAINT Событие перерисовки содержимого окна WM_COMMAND Событие поступления сообщения для (от) элемента управления WM_MOUSEMOVE Событие перемещения курсора мыши WM_LBUTTONDOWN Событие нажатия левой кнопки мыши WM_LBUTTONUP Событие отпускания левой кнопки мыши WM_LBUTTONDBLCLK Событие двойного нажатия левой кнопки мыши WM_RBUTTONDOWN Событие нажатия правой кнопки мыши WM_RBUTTONUP Событие отпускания правой кнопки мыши WM_RBUTTONDBLCLK Событие двойного нажатия правой кнопки мыши WM_KEYDOWN Событие нажатия клавиши на клавиатуре WM_KEYUP Событие отпускания клавиши на клавиатуре WM_CHAR Событие ввода символа WM_TIMER Событие срабатывания таймера
Дополнительные функции Функция определения существования окна BOOL Is. Window(HWND hwnd); Функция проверки наличия фокуса ввода у окна BOOL Is. Window. Enabled(HWND hwnd); Функция разрешения или запрета фокуса ввода у окна BOOL Enable. Window(HWND hwnd, BOOL flag); Функция передачи фокуса управления окну HWND Set. Focus(HWND hwnd); Функция поиска окна с заданными классом и названием HWND Find. Window(LPCTSTR lp. Class. Name, LPCTSTR lp. Window. Name);
Дополнительные функции Функция перемещения окна BOOL Move. Window(HWND hwnd, int x, int y, int n. Width, int n. Height, BOOL b. Repaint); Функция относительного перемещения окна: BOOL Set. Window. Pos(HWND hwnd, HWND hwnd. Insert. After, int x, int y, int n. Width, int n. Height, UINT u. Flags); hwnd. Insert. After может быть дескриптором существующего окна или одним из следующих значений: n HWND_BOTTOM – помещает окно ниже других окон, n HWND_NOTOPMOST – помещает временное или дочернее окно выше временных или дочерних окон, но ниже перекрывающихся окон, n HWND_TOP – помещает окно выше всех окон, n HWND_TOPMOST – то же, что HWND_NOTOPMOST, но окно сохраняет позицию после потери активности.
Дополнительные функции Вывод окна на передний план и передача ему управления: BOOL Set. Foreground. Window(HWND hwnd); Функция получения системных метрик: int Get. System. Metric(int n. Index); n. Index может принимать следующие значения: n SM_CXMIN – минимальная ширина окна, n SM_CYMIN – минимальная высота окна, n SM_CXSCREEN – ширина окна, n SM_CYSCREEN – высота окна, n SM_CYCAPTOIN – высота заголовка окна, n SM_CYMENU – высота меню окна.
Дополнительные функции Функция получения параметров окна: BOOL Get. Window. Rect(HWND hwnd, LPRECT rect); Функция получения параметров рабочей области окна: BOOL Get. Client. Rect(HWND hwnd, LPRECT rect); typedef struct{ LONG left; LONG top; LONG right; LONG bottom; } RECT; //Левый край //Верхний край //Правый край //Нижний край
Окно сообщения Вызов окна сообщения осуществляется с помощью функции: int WINAPI Message. Box( HWND hwnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type ); //Дескриптор окна //С-строка текста сообщения //С-строка заголовка сообщения //Флаги окна сообщения MB_ABORTRETRYIGNORE Стоп, Отмена, Пропустить MB_OK ОК MO_OKCANCEL ОК, Отмена MB_RETRYCANCEL Повтор, Отмена MB_YESNO Да, Нет MB_YESNOCANCEL Да, Нет, Отмена
Окно сообщения Флаг № кнопки MB_DEFBUTTON 1 Первая MB_DEFBUTTON 3 Третья MB_DEFBUTTON 1 Вторая MB_DEFBUTTON 4 Четвертая Флаг Вид иконки MB_ICONEXCLAMATION, MB_ICONWARNING Восклицательный знак MB_ICONINFORMATION, MB_ICONASTERIX Символ i MB_ICONQUESTION Знак вопроса MB_ICONSTOP, MB_ICONERROR, MB_ICONHAND Знак остановки
Окно сообщения MB_APPLMODAL Окно hwnd переводится в неактивное состояние на время работы окна сообщения MB_SYSTEMMODAL На время работы окна сообщения все другие приложения в неактивном состоянии MB_TASKMODAL На время работы окна сообщения текущее приложение в неактивном состоянии. Если hwnd=NULL, то все перекрывающие окна MB_HELP Добавляет кнопку «Справка» MB_RIGHT Текст выравнивается по правому краю MB_RTLREADING Отображает символы сообщения и текст заголовка в направлении справа налево MB_SETFOREGROUND Окно сообщения выдвигается на передний план