![]() |
Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | |
|
В каждом оконном приложении можно выделить 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; Прочитано: 619 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!