Здавалка
Главная | Обратная связь

Структура оконной функции. Класс окна и его характеристики.



Окно в Windows всегда создается на основе своего оконного класса. Оконный класс представляет собой запись с основными свойствами всех окон класса (форма курсора в рабочей области окна, адрес процедуры обработки сообщений). В Windows существует набор стандартных классов с заранее заданными свойствами. Как правило, любая программа для своего главного окна регистрирует оконный класс. Имя класса выбирается программистом произвольно.

Style – битовые флаги задающие начальные свойства всех окон данного класса

LpfnWndProc – указатель на callback-функцию вызываемую для обработки сообщений адресованных окнам данного класса. Callback-функция отличается от обычной тем, что вызывается из вне прикладной программы. В данном случае она вызывается ОС.

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

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

hInstance – дескриптор экземпляра приложения регистрирующего окно

hIcon - Дескриптор пиктограммы

hCursor – дескриптор курсора, который рисуется в пределах рабочей области окна

hbrBackground – дескриптор кисти для заливки фона

lpszMenuName – идентификатор меню тз ресурсов прикладных программ

lpsz ClassName – строковый идентификатор оконного класса в ОС.

Регистрация оконного класса выполняется с помощью функции

BOOL RegisterClass(WNDCLASS* wndClass);

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

Для создания окна существует функция

HWND CreateWindow( LPCTSTR lpClassName, // registered class name LPCTSTR lpWindowName, // window name DWORD dwStyle, // window style int x, // horizontal position of window int y, // vertical position of window int nWidth, // window width int nHeight, // window height HWND hWndParent, // handle to parent or owner window HMENU hMenu, // menu handle or child identifier HINSTANCE hInstance, // handle to application instance LPVOID lpParam // window-creation data );При создании окна этой функцией, функции обработчику приходит сообщение вместе с которым передается параметр Param. После вызова окно формируется в памяти и не отображается на экране.

Отображение окна. Для отображения используется функция BOOL ShowWindows(HWND hWnd, int nCmdShow);

Обновление рабочей области окна. Для обновления содержимого окна используется функция void UpdateWindow(HWND hWnd) она заставляет окно перерисовать окно свою область посылая сообщения WM_PAINT

Организация цикла обработки сообщений (Включает: прием сообщений, трансляция сообщении, диспетчеризация сообщений).

Включает прием(исключение сообщений из очереди сообщений – это делается 1 из функций BOOL(если сообщение WM_QUIT) GetMessage(MSG *msg, HWND hWnd, WORD msgFilterMin, DWORD msgFilterMax) & BOOL(если было сообщение удовлетворяло параметрам) PeakMessage(MSG *msg, HWND hWnd, WORD msgFilterMin, DWORD msgFilterMax, WORD RemoveMsg) msg – возврящаемое сообщение, если hWnd=0 то извлекаем сообщения для всех окон, далее указывается диапазон сообщений для приема, если оба 0 – то все сообщения, RemoveMsg – одна из 3х констант PM_REMOVE(удалять из очереди), PM_NOREMOVE, PM_NOYELD(при извлечении сообщений не передавать управления прикладным программам)), трансляцию, диспетчеризацию.

Реакцию программы на поступающие сообщения описывает оконная функция, которая вызывается из диспетчера. Сообщения, поступающие от клавиатуры, требуют трансляции, которая осуществляется сразу послу приема. Она преобразует сообщения о нажатии клавиши в символьные сообщения. Сообщения, генерируемые драйвером содержат так называемый виртуальный код клавиши, который определяет какая клавиша была нажата, но не определяет символьное значение этой клавиши. Функция TranslateMessage не изменяя сообщения, помещает в очередь сообщений еще 1 сообщение (WM_CHAR). Диспетчеризация сообщений заключается в вызове соответствующей оконной функции. Делается это опосредованно с помощью функции DWORD DispatchMessage(MSG *msg). Результат обработки сообщений возвращается как результат этой функции.

Практически вся логика работы программы под Windows размещается в оконных функциях.

Оконная функция

RESULT CALLBACK WndProc(HWND Wnd, UINT message, WPARAM wParam, LPARAM lParam);

Описание функции включает директиву CALLBACK, которая делает эту функцию доступной для вызова из вне приложения. Параметры оконной функции соответствует полям структуры MSG. Структура MSG описывает сообщение.

typedef struct tagMSG { HWND hwnd; //дескриптор окна, в котором возникло сообщение UINT message; //код сообщения (WM_<сообщение>. Пользовательские сообщения начинаются с WM_USER)) WPARAM wParam; //Доп. Информация (зависит от типа сообщений) LPARAM lParam; //Доп. Информация (зависит от типа сообщений) DWORD time; //Система помещает время в миллисекундах, которое истекло с момента запуска //системы, до постановки сообщения в очередь POINT pt; //Указывает позицию курсора мыши в экранных координатах на момент возникновения //сообщения

} MSG, *PMSG;

Взаимоотношения между окнами строится по принципу родитель-потомок. Родительское окно может владеть 1 или несколькими дочерними окнами. Дочерние всегда располагаются поверх родительского и всегда закрываются вместе с ним. Родительское окно может быть дочерним для другого окна. Если оно создается без родителя, то Windows назначает ему в качестве родителя Desktop.

Источники сообщений:

· Пользователь генерирует сообщения воздействуя на внешние устройства(мышь…)

· Сама ОС посылает сообщения для уведомления ПО о событиях

· Программа может вызывать функции ОС, результатом которой может являться посылка сообщения ПО

· ПО может посылать сообщение самой себе

· ПО может посылать сообщения другим прикладным программам

Оконная функция обрабатывает WM_DESTROY (как минимум). Оно посылается сразу после закрытия окна. Сообщение вызывается в результате функции DestroyWindow(). Эту функцию вызывает ОС. Приход сообщения WM_DESTROY означает, что происходит удаление окна. В этот момент программа должна удалить рабочие данные, связанные с окном. Если сообщение WM_DESTROY обрабатывается в главной оконной функции программы, то необходимо вызвать функцию:

VOID PostQuitMessage(int exitCode), которая генерирует WM_QUIT.

Все необработанные оконной функцией сообщения должны быть обработаны стандартной оконной функцией, вызываемой по умолчанию LRESULT DefWindwProc(HWND hWnd, UINT message). Текст этой функции – секрет Microsoft ☺

Посылка сообщений

Для посылки сообщений из программы существуют следующие функции:

· PostQuitMessage(int);

· BOOL PostMessage(HWND, UINT, WPARAM, LPARAM); Помещает сообщение в очередь прикладной программы и возвращает управление не дожидаясь его обработки. Такое сообщение будет обработано при подходе очереди. TRUE - сообщение успешно поставлено в очередь.

· LRESULT SendMessage(HWND, UINT, WPARAM, LPARAM); Она фактически вызывает оконную функцию, дожидается ее выполнения и возвращает значение, которое вернула оконная функция.

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

При каждом нажатии и отпускании левой кнопки мыши ОС посылает программе сообщение WM_LBUTTONDOWN и WM_LBUTTONUP соответственно. При перемещении мыши ОС помещает в очередь сообщение WM_MOUSEMOVE. Если в оконном классе окна над которым находится указатель мыши установлен стиль CS_DBLCLKS, то окно способно получать сообщение двукратного щелчка. Когда двукратные щелчки разрешены, ОС устанавливает один из внутренних таймеров заданный в CotrolPanel. Если пользователь в пределах этого интервала совершает двойное нажатие, то ОС вместо сообщения о нажатии посылает сообщение двукратного щелчка WM_LBUTTONDBLCLK.

В сообщении от мыши параметры имеют следующий смысл: WPARAM – определяет состояние кнопок мыши и клавиш Ctrl & Shift. LPARAM – младшие 2 байта кодируют координату X, старшие – Y.

Обработка сообщений от клавиатуры

При нажатии и отпускании обычной клавиши ОС генерирует сообщение WM_KEYDOWN & WM_KEYUP.

Если нажаты системные клавиши WM_SYSKEYDOWN & WM_SYSKEYUP (Они соответствуют системному нажатию и отпусканию. Системное нажатие происходит с клавишей Alt !!!).

Если пользователь нажал клавишу и удерживает ее, То происходит автоповтор клавиатуры. ОС автоматически начинает помещать в очередь сообщений WM_KEYUP. В результате на 1 сообщение WM_KEYDOWN может быть несколько WM_KEYUP. Если очередь сообщений забивается, то в параметре сообщений WM_KEYDOWN ОС начинает увеличивать счетчик повторов. wParam – код виртуальный. Для символьных сообщений там символьный код. При отпускании клавиши TranslateMessage помещает в очередь сообщений WM_DEADCHAR (WM_SYSDEADCHAR). lParam во всех типах – набор битовых флагов:

· Счетчик повтора

· Индикатор расширенной клавиши

· Индикатор системной клавиши (удерживался ли Alt)

· Индикатор предыдущего состояния, который показывает - была ли до этого нажата эта клавиша

· Индикатор текущего состояния

Параметры клавиатурных сообщений не несут информацию о состоянии Ctrl & Shift. Чтобы ее получить нужно вызвать функцию GetKeyState(UINT virtkKey). Она принимает код клавиши и возвращает ее состояние нажата/отпущена (включена/выключена). Эта функция синхронизирована с моментом посылки последнего клавиатурного сообщения. Т.е. она возвращает состояние клавиши не на момент ее вызова, а на момент последнего сообщения от клавиатуры.

Сообщение Windows.

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







©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.