Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Структура оконного приложения



В каждом оконном приложении можно выделить 4 части.

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

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

3) Цикл выбора сообщений из очереди

4) Процедура обработки сообщений

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

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

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

– EDIT – строка ввода текста;

– LISTBOX – список;

– COMBOBOX – выпадающий список со строкой редактирования;

– BUTTON – кнопка;

и многие другие.

Основное окно, как правило, принадлежит классу, зарегистрирован­ному в программе. Каждый класс характеризуется именем, которое является символьной строкой, заканчивающейся символом с кодом 0, с учетом регистра букв (например, EDIT и Edit разные классы). Регистрация класса осуществляется системным вызовом RegisterClass либо RegisterClassEx. Рассмотрим расширенную регистрацию класса окна с помощью RegisterClassEx.

Синтаксис: ATOM RegisterClassEx(CONST WNDCLASSEX* lpwc)

Возвращаемое значение АТОМ. В случае успешного выполнения – атомарное значение, являющееся уникальным идентификатором нового класса, который был зарегистрирован; в ином случае, возвращаемое значение равно 0.

lpwc CONST WNDCLASSEX*. Указатель на структуру данных WNDCLASSEX, которая определена следующим образом:

typedef struct tagWNDCLASSEX

{

UINT cbSize;

UINT style;

WNDPROC lpfnWndProc;

int cbClsExtra;

int cbWndExtra;

HINSTANCE hlnstance;

HICON hlcon;

HCURSOR hCursor;

HBRUSH hbrBaclcground;

LPCTSTR lps zMenuName;

LPCTSTR IpszClassName;

HICON hlconSm;
} WNDCLASSEX;

Рассмотрим основные поля структуры.

cbSize UINT. Размер структуры в байтах. Установите в качестве значения этого члена sizeof(WNDCLASSEX) перед использованием структуры в функ­ции.

Style UINT. Параметр style может представлять собой один или несколько стилей, объединенных с помощью двоичного опе­ратора OR (|). Список стилей см. в [Simon стр. 56-78].

lpfnWndProc WNDPROC. Указатель на функцию обратного вызова окна для обработ­ки сообщений. (Описание функции обратного вызова WndProc приведе­но ниже.)

cbClsExtra int. Число дополнительных байтов, которые должны быть распределены в конце структуры класса окна для хранения информации. См. описание функции SetClassLong [Simon].

cbWndExtra int. Число дополнительных байтов, которые должны быть распределены вслед за экземпляром окна. Если в приложении для регистрации диалого­вого окна, созданного с использованием директивы CLASS в файле ресур­са, применяется структура WNDCLASS, приложение должно установить значение этого члена в DLGWINDOWEXTRA.

hInstance HINSTANCE. Дескриптор экземпляра, в котором находится оконная процедура для этого класса (обычно выступает дескриптор потока).

hIcon HICON. Дескриптор пиктограммы, которая предназначена для этого класса окна. Если это значение установлено в NULL, приложение должно выводить пиктограмму каждый раз, когда пользователь сворачивает окно.

hCursor HCURSOR. Дескриптор курсора, который предназначен для этого класса окна. Если это значение установлено в NULL, приложение должно ус­танавливать курсор каждый раз, когда курсор мыши уходит за пределы окна.

hbrBackground HBRUSH. Дескриптор кисти, которая предназначена для отображения фона окна. Вместо кисти может использоваться один из системных цве­тов, [Simon стр. 56-78]. Прибавляйте 1 к этим значениям для опре­деления класса.

lpszMenuName LPCTSTR. Указывает на строку с нулевым символом в конце, содержа­щую имя меню, применяемого по умолчанию для этого класса. Устанав­ливается в NULL, если класс не имеет меню, применяемого по умолча­нию.

lpszClassName LPCTSTR. Указывает на строку с нулевым символом в конце, содержащую имя класса. Это имя должно использоваться в параметре lpszClassName функции CreateWindow.

hIconSm HICON. Дескриптор пиктограммы, которая предназначена для использования в строке заголовка окон, созданных с помощью этого класса. Разме­ры пиктограммы должны быть равны 16x16. Если этот член имеет значе­ние NULL, система ищет ресурс пиктограммы, указанный членом hIcon, чтобы найти пиктограмму подходящего размера для использования в качестве малой пиктограммы.

Во время регистрации класса окна устанавливается соответствие между окном класса и его обработчиком (В дальнейшем функцию обработчик сообщений окна будем называть WndProc).

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

Создание окна осуществляется функциями CreateWindow или CreateWindowEx.

С помощью CreateWindowEx создается перекрываемое, всплывающее или дочернее окно с расширенным стилем; во всем остальном эта функция иден­тична CreateWindow.

Синтаксис: HWND CreateWindowEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hwndParent, HMENU hmenu, HINSTANCE hInstance, LPVOID lpvParam)

Параметры:

dwExStyle DWORD. Указывает расширенный стиль, который используется для создания окна. В качестве расширенного стиля может применяться один из сти­лей, перечисленных в табл. 3.5.

lpszClassName LPCTSTR. Указатель на чувствительную к регистру строку с нулевым символом в конце, содержащую допустимое имя класса для окна или це­лочисленное атомарное значение. Имя класса может быть создано с по­мощью функции RegisterClass; оно также может представлять собой один из существующих классов, перечисленных в табл. 3.3. Если параметр lpszClassName представляет собой атомарное значение, он должен быть со­здан с помощью предварительного вызова функции GlobalAddAtom.

lpszWindowName LPCTSTR. Указатель на строку с нулевым символом в конце, которая со­держит имя окна. Имя окна отображается в том месте, которое соответ­ствует конкретному стилю окна.

dwStyle DWORD. Стиль окна, которое должно быть создано. Стиль состоит из значений, объединяемых друг с другом с помощью двоичного оператора OR. В качестве примера стиля можно указать WS_CHILD | ES_LEFT. Стили могут составляться из значений, перечисленных в [Simon]

х int. Горизонтальная позиция левого верхнего угла окна или элемента управления, который должен быть создан. Если позиция не важна, исполь­зуется значение CW_USEDEFAULT. Позиции х и у определяются относительно левого верхнего угла экрана или, в случае дочерних окон и элементов управления, родительского окна. Все размеры измеряются в пикселях, поэтому дисплей с разрешающей способностью 640x480 имеет размеры 640 пикселей по горизонтали и 480 пикселей по вертикали.

y int. Вертикальная позиция левого верхнего угла окна или элемента управления, который должен быть создан. Если позиция не важна, использу­ется значение CW_USEDEFAULT.

nWidth int. Ширина окна или элемента управления по горизонтали. Если ширина не важна, используется значение CW_USEDEFAULT.

пHeight int. Высота окна или элемента управления по вертикали. Если высота не важна, используется значение CW_USEDEFAULT.

hwndParent HWND. Дескриптор родительского объекта окна или элемента управления. Если нет родительского окна, используется значение NULL. Если родительское окно не задано, данное окно не будет уничтожено автома­тически по завершении работы приложения. Для удаления окна перед зак­рытием приложения используется DestroyWindow.

hmenu HMENU. Дескриптор меню окна. Используйте значение NULL, если должно применяться меню класса. Для элементов управления в качестве hmenu устанавливается целочис­ленное значение, представляющее собой идентификатор создаваемого эле­мента управления. Во всех сообщениях WM_COMMAND при выполне­нии какого-либо действия с этим элементом управления указывается данный идентификатор.

hInstance HINSTANCE. Дескриптор экземпляра прикладного модуля, создающего окно или элемент управления. В Windows 2000 это значение игнорируется.

lpvParam LPVOID. Указатель на данные, которые должны быть переданы в качестве параметра LPARAM сообщения WM_CREATE. При создании окна MDICLIENT используйте указатель на структуру CLIENTCREATESTRUCT. Для большинства окон и элементов управления устанавливайте значение lpvParam в NULL.

Возвращаемое значение: HWND. Возвращается дескриптор окна, принадлежащий вновь созданному окну, если функция была выполнена успешно; NULL, если окно нельзя было создать.

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

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

Когда функция CreateWindow создает главное окно приложения, она направляет в функцию WndProc пять сообщений. Функция WndProc обычно обрабатывает толь­ко сообщение WM_CREATE, а остальные четыре сообщения передает функции DefWindowProc. Приложение использует сообщение WM_CREATE при инициализа­ции элементов управления окна. Сообщения перечислены в таблица 1.1 в порядке их получения.

Таблица 1.1 – Сообщения, вырабатываемые функцией CreateWindow

Сообщение Описание
WM_GETMINMAXINFO Определить размер и позицию создаваемого окна.
WM_NCCREATE Должна быть вскоре создана неклиентская область окна. Память для окна распределена и линейки прокрутки инициализированы.
WM_NCCALCSIZE Размер и позиция клиентской области окна определены.
WM_CREATE Извещение о том, что должно быть создано окно. При получении этого сообщения выполняется инициализация окна.
WM_SHOWWINDOW Окно должно быть вскоре отображено.

При получении сообщения WM_CREATE, WndProc должна вызвать CreateWindow либо CreateWindowEx для каждого дочернего элемента управления и, если необходимо, инициализировать собственные структура данных.

3) Цикл выбора сообщений

Поток или процесс выбирает сообщения из очереди с использованием цикла обра­ботки сообщений. Цикл обработки сообщений обычно имеет следую­щий вид:

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

{TranslateMessage(&msg);

DispatchMessage(&msg);

}

Функция GetMessage выбирает сообщение из очереди сообщений. За GetMessage следуют функции TranslateMessage и DispatchMessage. Функция TranslateMessage определяет, является ли поступившее сообщение сообщением от алфавитно-цифровой клавиатуры, и если да, то посылает ещё одно сообщение WM_CHAR, содержащее символ нажатой клавиши.

При регистрации класса окна было установлено соответствие WndProc всем окнам этого окна. Во время создания конкретного окна устанавливается однозначное соответствие между WndProc и дескриптором окна. На основании этой информации и дескриптора окна, со­держащегося в структуре сообщения, функция DispatchMessage определяет обработчик сообщений окна (WndProc) и отправляет данные сообщения в функцию WndProc этого окна. По умолчанию функцией WndProc считается функция, содержащаяся в оп­ределении класса окна, но ее можно заменить другой, определив подкласс окна.

4) Процедура обработки сообщений (WndProc)

WndProc – является обобщенным названием всех обработчиков сообщений окна в программе. Каждая программа может иметь столько обработчиков, сколько окон создается в программе (при условии, что все они принадлежат разным классам). Соответственно каждая подпрограмма обработчик сообщений окна должна иметь своё уникальное имя.

WndProc осуществляет реакцию окна, на поступающие сообщения. Как было указано выше, данная функция вызывается из DispatchMessage (т.е. присутствует косвенный вызов этой функции, а не прямой).

Определение WndProc должно подчиняться следующему синтаксису:

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

Параметры: Все параметры имеют размер двойное слово.

hWnd HWND. Дескриптор окна, получающего сообщение.

uMsg UINT. Сообщение (WM_PAINT и т.д.). Это значение и следующие два значения будут получены функцией WndProc приложения при отправке сообщения приложению.

wParam WPARAM. Данные wParam, переданные с сообщением.

lParam LPARAM. Данные lParam, переданные с сообщением.

Возвращаемое значение: LRESULT. Значение зависит от обрабаты­ва­емо­го сообщения. Это значение возвращается из функции WndProc приложения.

Как правило, WndProc реализуется в виде структуры switch case.

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {

switch(uMsg) {

case WM_CREATE: {... }; break;

...

case WM_CHAR: {... }; break;

...

case WM_COMMAND: {

switch(wParam) {

case 100: {... }; break;

...

case 1000: {... }; break;

}

...

case WM_DESTROY: {... }; break;

default:

return(DefWindowProc(hWnd, uMsg, wParam, lParam));

}

return(0L);

}

Если сообщение не обрабатывается данной функцией, то она должна вызвать DefWindowProc и передать ей принятые параметры.

Помимо обработки сообщений возникающих от аппаратуры ЭВМ часто возникает необходимость передачи воздействиё или данных другим окнам или между элементами управления одного окна. В этом случае можно послать сообщение этому окну либо другому элементу управления. Посылка сообщений осуществляется функциями SendMessage, PostMessage.

SendMessage посылает сообщение в очередь своего потока, а PostMessage может посылать сообщения в другие потоки и процессы.

Функция SendMessage отправляет сообщение другому окну и ждет ответа. Это сообщение обходит очередь сообщений и все действия над ним выполняются немедленно. В приложениях функция SendMessage часто используется для обеспече­ния взаимодействия с окнами таких элементов управления, как кнопки и списки, если в программе есть ряд дочерних окон, каждое из которых имеет отдельные функции обработки сообщений. Окно-отправитель пере­запускает обработку только после того, как окно-получатель обработает сообщение и возвратит результат.

Синтаксис: LRESULT SendMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

Параметры: все параметры имеют размер двойное слово.

hWnd HWND. Дескриптор окна, которое должно получить сообщение. Если это значение установлено в HWND_BROADCAST, сообщение будет отправ­лено всем окнам верхнего уровня в системе.

uMsg UINT. Сообщение, которое должно быть отправлено.

wParam WPARAM. Значение wParam для этого сообщения.

lParam LPARAM. Значение lParam для этого сообщения.

Возвращаемое значение LRESULT. Возвращаемое значение зависит от отправленного сообщения.

Функция PostMessage позволяет поместить сообщение в очередь, связанную с нитью, которая создала окно, и выполнить возврат, не ожидая от­вета. Сообщения, которые находятся в очереди, могут быть выбраны пу­тем вызова функций GetMessage и PeekMessage.

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

Синтаксис: BOOL PostMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

Параметры:

hWnd HWND. Дескриптор окна, принимающего выставленное сообщение. Если в качестве значения этого параметра установлено HWND_BROADCAST, сообщение будет выставлено для всех окон верхнего уровня в системе. Если в качестве значения этого параметра установлено NULL, функция PostMessage ведет себя аналогично PostThreadMessage при обработке со­общений, предназначенных для текущей нити.

uMsg UINT. Сообщение, которое должно быть выставлено.

wParam WPARAM. Значение wParam, которое должно быть передано с сообщением.

lParam LPARAM. Значение lParam, которое должно быть передано с сообщением.

Возвращаемое значение: BOOL. В случае успешного выполнения возвра­щае­мое значение – TRUE; в ином случае возвращаемое значение – FALSE.

Каждый элемент управления обрабатывает определенное множество сообщений, перечень которых см. [http://msdn.microsoft.com/en-us/library/bb773169(VS.85).aspx]

Посылая сообщения в элементы управления окна можно управлять их состоянием.





Дата публикования: 2015-01-13; Прочитано: 586 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.015 с)...