01 - Основы создания графических приложений в системе Windows

0

No comments posted yet

Comments

Slide 1

Основы создания графических приложений в системе Windows

Slide 2

Графический интерфейс пользователя Разновидность пользовательского интерфейса, в котором элементы интерфейса представленные пользователю на дисплее, исполнены в виде графических изображений

Slide 3

Функция WinMain() Подобно тому как функция main() является точкой входа консольного приложения, функция WinMain является точкой входа в GUI-приложение системы Windows Задачи функции WinMain: Инициализация приложения Отображение главного окна приложения Цикл выборки и обработки сообщений Возврат целочисленного значения в операционную систему

Slide 4

Простейшее приложение Windows int APIENTRY WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nCmdShow*/) { // возвращаемся в операционную систему return 0; }

Slide 5

Windows и Окна В GUI приложении Windows окно – это прямоугольная область на экране, служащая для отображения выводимой информации и получения пользовательского ввода Windows – многозадачная ОС Несколько одновременно запущенных приложений Область экрана – общая для всех окон в системе Только одно окно может в заданный момент времени получать вводимую информацию от пользователя

Slide 7

Главное окно приложения Служит для обработки сообщений и получения данных, введенных пользователем Является родительским для окон, создаваемых в приложении Возможно существование нескольких главных окон в рамках одного приложения Приложение Microsoft Word Интернет –браузер Такие приложению завершают работу после закрытия всех своих окон

Slide 8

Элементы окна

Slide 9

Области окна Клиентская область Часть окна, служащая для вывода текста и графики, а также для получения пользовательского ввода Управляется приложением Неклиентская область область заголовка, меню, рамку, области прокрутки, кнопки минимизации/максимизации и закрытия окна Как правило, управляется операционной системой

Slide 10

Элементы управления (controls) Вспомогательные окна, служащие для ввода и вывода определенной информации Поля редактирования (Edit box) Статический текст (Static) Кнопки (Button, Radio button, Check Box) Списки (List box, Combo box, List) Деревья (Tree control) Создаваемые пользователем компоненты

Slide 11

Диалоговые окна Диалоговое окно – это окно, содержащее один или более элементов управления Обычно не содержат меню или полос прокрутки, кнопок минимизации/максимизации Используются для ввода пользователем различных данных Типы диалоговых окон Модальные Немодальные

Slide 12

Диалоговые окна Модальное окно Немодальное окно

Slide 13

Стандартные диалоговые окна Окно выбора файла Окно выбора шрифта Окно выбора цвета Окно выбора принтера Окно выбора папки Окно настройки свойств страницы

Slide 14

Пример диалогового окна

Slide 15

Окна сообщений (Message boxes) Специальные диалоговые окна, служащие для отображения коротких сообщений пользователю: Предупреждение об ошибке Уведомление о завершении результатах операции

Slide 16

Пример окна сообщений

Slide 17

Приложение HelloWorld int APIENTRY WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nCmdShow*/) { MessageBox( NULL, "Hello World", "Hi", MB_OK | MB_ICONINFORMATION ); return 0; }

Slide 18

Окно рабочего стола (Desktop Window) Данное окно автоматически создается при загрузке ОС Окно рабочего стола служит для отображения заднего фона окна и служит основой для размещения других окон

Slide 19

Создание окна При создании окна приложение должно указать следующие атрибуты окна: Имя класса окна Имя окна Стиль окна и дополнительный стиль окна Положение и размер окна Дескриптор родительского окна или окна-владельца Дескриптор меню или дочернего окна Дескриптор экземпляра приложения Данные, характерные для приложения

Slide 20

Имя класса окна (Window Class Name) Класс окна – это определенный набор атрибутов, используемый в качестве шаблона при создании окон Каждое окно относится к определенному классу На основе класса окна приложение может создать произвольное количество окон Окна, принадлежащие к одному классу ведут себя сходным образом Кнопки нажимаются Выпадающие списки выпадают Поля редактирования текста позволяют редактировать текст

Slide 21

Предопределенные классы окон В системе зарегистрированы предопределенные классы окон BUTTON LISTBOX COMBOBOX STATIC EDIT MDICLIENT RICHEDIT_CLASS SCROLLBAR И др.

Slide 22

Регистрация класса окна Главное окно приложения не имеет предопределенного класса, поэтому приложению необходимо зарегистрировать класс своего главного окна самостоятельно Регистрация класса окна осуществляется при помощи функции RegisterClassEx()

Slide 23

Имя окна Строка, идентифицирующая данное окно для пользователя Главное окно приложения и диалоговые окна отображают имя окна в строке заголовка Некоторые элементы управления – внутри клиентской области Edit box, Static text, Button Некоторые элементы управления – не отображают вообще List box, Combo box

Slide 24

Стили окна Стиль окна – именованная целочисленная константа, определяющая определенные аспекты поведения и внешнего вида окна Тип рамки Наличие и вид заголовка Наличие кнопок максимизации/минимизации И т.п. Окно может иметь несколько стилей окна Объединяются при помощи операции | Некоторые стили могут быть применены ко всем окнам, в то время как другие – к окнам определенного класса Стиль ES_PASSWORD применим только к полям редактирования текста Стиль WS_VISIBLE – к любым окнам

Slide 25

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

Slide 27

Дескриптор родительского окна Некоторые окна могут иметь родителей такие окна называются дочерними Родительские окна определяют систему координат своих дочерних окон Окна без родителей – окна верхнего уровня (Top Level Window)

Slide 28

Идентификатор меню или идентификатор дочернего окна Дочерние окна могут иметь идентификатор дочернего окна – уникальное значение, ассоциированное с данным дочерним окном Система позволяет получить дескриптор дочернего окна по его идентификатору при помощи функции GetDlgItem Окна, не являющиеся дочерними, могут иметь меню

Slide 29

Окно с меню

Slide 30

Дескриптор экземпляра приложения (HINSTANCE) Является идентификатором экземпляра запущенного приложения, либо загруженного DLL-модуля Передается в качестве параметра функции WinMain Для DLL-модулей – в DLL Main Используется при создании окон, работы с ресурсами, потоками выполнения и т.п. Разные модули внутри одного процесса могут регистрировать свои собственные классы окон, даже совпадающие по имени

Slide 31

Дескриптор Окна (Window Handle) Каждое окно в системе после своего создания получает дескриптор – уникальный идентификатор, однозначно определяющий данное окно в системе Данный идентификатор имеет тип HWND Используется для управления созданным окном

Slide 32

Создание окна на основе зарегистрированного класса Создание окна осуществляется при помощи функции CreateWindowEx() После своего создания окно является невидимым Чтобы показать его, необходимо вызвать функцию ShowWindow() Можно создать окно видимым изначально, задав ему стиль WS_VISIBLE при его создании

Slide 33

Сообщения Обработка сообщений лежит в основе работы приложений Windows Сообщения создаются системой и приложением в ответ на каждое событие, происходящее в Windows: Движения мыши, нажатие клавиш, события таймера и т.п. Многие GUI-приложения проводят большую часть времени в ожидании сообщений Это позволяет оптимально использовать ресурсы процессора в условиях параллельной работы нескольких приложений

Slide 34

Что такое сообщение? Сигнал, посылаемый приложению системой или другими приложениями при наступлении определенного события В Windows SDK структура MSG определена следующим образом: typedef struct tagMSG { HWND hwnd; // дескриптор окна UINT message; // идентификатор сообщения WPARAM wParam; // параметр wParam LPARAM lParam; // параметр lParam DWORD time;// время отправки сообщения POINT pt; // положение курсора мыши в момент создания сообщения } MSG;

Slide 35

Маршрутизация сообщений и очередь сообщений Очередь сообщений – объект для временного хранения сообщений Системная очередь сообщений Хранит сообщения от устройств ввода Очередь сообщений GUI-потока (thread) Получает сообщения из системной очереди сообщений, адресованные окнам, созданным в данном потоке

Slide 37

Обработка сообщений GUI-поток выбирает сообщения из своей очереди с использованием цикла выборки сообщений

Slide 38

Цикл выборки (обработки) сообщений Функция GetMessage() осуществляет выбор сообщения из очереди сообщений Функция TranslateMessage() осуществляет перевод нажатий виртуальных клавиш в символьные сообщения, которые будут считаны при следующем вызове GetMessage() или PeekMessage() Функция DispatchMessage() перенаправляет сообщение из цикла обрабоки в соответствующую оконную процедуру

Slide 39

Простейший цикл обработки сообщений MSG msg; BOOL res; while ((res = GetMessage(&msg, NULL, 0, 0)) != 0) { if (res == -1) { // произошла ошибка - нужно обработать ее и, вероятно, // завершить работу приложения } else { // Если это сообщение о нажатии виртуальной клавиши, // то добавляем в очередь сообщений сообщения, несущие информацию о // коде вводимого пользователем символа TranslateMessage(&msg); // передаем сообщение в соответствующую оконную процедуру DispatchMessage(&msg); } }

Slide 40

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

Slide 41

Регистрация оконной процедуры Регистрация оконной процедуры происходит одновременно с регистрацией класса окна Приложение может создать произвольное количество окон, относящихся к данному классу и использующих одну и ту же оконную процедуру Аккуратная работа с глобальными переменными Оконная процедура должна быть реентерабельной, т.е. должна позволять ее повторный вызов явным или неявным образом из самой себя. Минимум локальных переменных внутри оконной процедуры

Slide 42

Требования к оконной процедуре Одна оконная процедура может обрабатывать несколько окон одновременно Умеренное использование глобальных переменных Оконная процедура должна быть реентерабельной Возможен неявный рекурсивный вызов оконной процедуры Минимизировать количество локальных переменных внутри оконной процедуры Борьба со Stack Overflow

Slide 43

Структура оконной процедуры Оконная процедура имеет следующий прототип: LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

Slide 44

Оконная процедура по умолчанию Для многих оконных сообщений в системе предусмотрено поведение по умолчанию Перемещение окон Минимизация/максимизация Реакция на движения мыши Все сообщения, не обрабатываемые явно в оконной процедуре приложения, должны направляться в оконную процедуру по умолчанию при помощи вызова функции DefWindowProc()

Slide 45

Пример простейшей оконной процедуры главного окна приложения LRESULT CALLBACK MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }

Slide 46

Перегрузка (Subclassing) оконной процедуры При создании окна система выделяет память для хранения информации об окне, включая адрес оконной процедуры При посылке сообщения окну система извлекает адрес оконной процедуры из информации, специфичной для окна с указанным дескриптором, и вызывает оконную процедуру Subclassing – технология, позволяющая перехватывать и обрабатывать в обход оригинальной оконной процедуры

Slide 47

Принцип SubClassing’а Приложение может заменить адрес оконной процедуры отдельно взятого окна или оконного класса адресом собственной оконной процедуры подкласса (subclass procedure) Subclassing возможет лишь в рамках одного процесса После этого новая оконная процедура сможет обрабатывать сообщения окна: Передача их в оригинальную оконную процедуру без изменения Модификация сообщения с последующей передачей его в оригинальную оконную процедуру Обработка сообщения

Slide 48

Виды Subclassing’а Instance subclassing У созданного окна заменяется адрес оконной процедуры Global Subclassing Подменяется адрес оконной процедуры целого класса окон

Slide 49

Superclassing Это технология, позволяющая создать новый класс окна с базовой функциональностью существующего класса + добавить собственную функциональность Часто применятся для расширения функционала существующих стандартных элементов управления

Slide 50

Часто используемые сообщения

Slide 51

Сообщение WM_CREATE Уведомление о том, что окно создается. Вызывается в ходе создания окна при помощи CreateWindowEx()

Slide 52

Сообщение WM_MOVE Посылается окну после его перемещения Сообщение WM_MOVING посылается окну во время его перемещения Приложение может изменить положение окна в обработчике данного сообщения

Slide 53

Сообщение WM_SIZE Посылается окну после изменения его размеров Сообщение WM_SIZING посылается во время изменения размеров окна Приложение может изменить размеры и положение окна в обработчике данного сообщения

Slide 54

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

Slide 55

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

Slide 57

Схема работы Каждое окно должно быть ответственным за корректное и своевременное отображение содержащейся в нем информации

Slide 58

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

Slide 59

Недействительная область окна WM_ERASEBKGND WM_PAINT Приложение очищает задний фон окна Приложение производит рисование графического содержимого окна Область окна требующая отрисовки содержимого

Slide 60

Сообщение WM_ERASEBKGND Посылается окну в тот момент, когда его фон должен быть очищен Это подготовка недействительной области окна к отрисовке Приложение может использовать это сообщение для заполнения заднего фона окна каким-нибудь узором Оконная процедура по умолчанию просто заполняет задний фон кистью, указанной при регистрации класса окна

Slide 61

Сообщение WM_PAINT Посылается окну в том случае, когда какая-то часть его клиентской области требует перерисовки Приложение вызывало функцию RedrawWindow() или UpdateWindow() Область окна стала недействительной при сворачивании/перемещении окна на верхнем уровне

Slide 62

Обработка сообщения WM_PAINT LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_PAINT: { PAINTSTRUCT ps; HDC dc = BeginPaint(hWnd, &ps); // выполняем рисование // ... EndPaint(hWnd, &ps); } break; // обработка остальных сообщений } }

Slide 63

Сообщение WM_DESTROY Посылается окну после того как оно убрано с экрана перед его уничтожением Дочерние окна получают данное сообщение вслед за родительским При уничтожении главного окна приложения обычно происходит вызов функции PostQuitMessage()

Slide 64

Сообщение WM_QUIT Данное сообщение посылается потоку (а не окну) в качестве запроса на завершение его работы Функция GetMessage() возвращает значение 0 при извлечении сообщения WM_QUIT

Slide 65

Шаги для создания оконного приложения для ОС Windows Регистрация класса окна Создание главного окна приложения Выборка сообщений из цикла обработки сообщений Обработка сообщений в оконной процедуре окна

URL: