Функция окна

Функция окна описывает реакцию окна на поступающие сообщения. Она от обычных функций отличается следующим:

- имеет стандартные тип возврата и список формальных параметров;

- вызывается только операционной системой при поступлении сообщения окну;

- сообщения, которые не обрабатываются функцией окна, возвращаются операционной системе.

Есть еще одно отличие. В объектно-ориентированном программировании методы изменения параметров состояния объекта (функции-члены) обычно описывают отдельно. Функция окна реализует единственный метод для изменения всех параметров состояния окна.

Имя функции окна – это обычное имя, определяемое разработчиком. При регистрации класса операционная система запоминает указатель на эту функцию.

Рассмотрим пример описания функции окна.

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,

WPARAM wParam, LPARAM lParam)

{

//Описание локальных переменных

static short cx, cy, left, top;

switch (msg) //Обработка сообщения

{

case WM_CREATE: {...; return 0;}

case WM_MOVE:

{ left = LOWORD(lParam);

top = HIWORD(lParam);

return 0;

}

case WM_SIZE:

{ cx = LOWORD(lParam);

cy = HIWORD(lParam);

return 0;

}

case WM_COMMAND: //Обрабатываем команды

{

switch (LOWORD(wParam))

{

case CM_FILE_EXIT:

{ DestroyWindow(hwnd); return 0; }

//Далее могут быть ветви других команд

}

return 0;

}

case WM_DESTROY:

{...; PostQuitMessage(0); return 0;}

}

return DefWindowProc(hwnd, msg, wParam, lParam);

}

Заголовок функции окна определен соглашениями Windows и имеет вид:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,

WPARAM wParam, LPARAM lParam)

Тип возврата LRESULT равноценен типу signed long. Модификатор CALLBACK указывает на соглашения о том, что эта функция вызывается операционной системой (такие функции называют функциями обратного вызова).

Имена типов UINT, WPARAM, LPARAM описаны следующим образом:

typedef unsigned int UINT;

typedef UINT WPARAM;

typedef LONG LPARAM;

Параметр hWnd – дескриптор окна-адресата, a msg, wParam и lParam описывают полученное сообщение. Например, параметр msg принимает код сообщения.

Рассмотрим, каким сообщениям соответствуют используемые в примере имена констант. В Windows описаны несколько сот кодов сообщений с префиксом WM_.

Код WM_CREATE поступает от функции CreateWindow (о ней речь пойдет ниже) перед созданием окна. Если после обработки этого сообщения функции CreateWindow возвращается значение -1, то окно не создается.

Код WM_SIZE функция окна получает после изменения размеров окна, a WM_MOVE – после перемещения левого верхнего угла рабочей области окна. Если при изменении размеров окна изменились координаты левого верхнего угла рабочей области, то функция окна сначала получает код WM_MOVE, а затем – WM_SIZE. После изменения режима отображения окна функция окна получает код WM_SIZE, а затем – WM_MOVE.

Код WM_COMMAND функция окна получает при поступлении команды. Тогда младшее слово параметра wParam содержит код команды. Разработчик свои сообщения часто связывает с командами меню и описывает идентификаторы для этих команд. Например, для идентификатора CM_FILE_EXIT команды меню текст приложения должен содержать макроопределение вида

#define CM_FILE_EXIT 3001

Код WM_DESTROY функции окна посылают перед разрушением окна. В примере функция окна, вызывая функцию DestroyWindow, сама себе отправляет сообщение WM_DESTROY.

Рассмотрим сообщения от мыши. Пусть курсор мыши находится над рабочей областью окна. После нажатия левой клавиши мыши функция окна получит код WM_LBUTTONDOWN, а правой клавиши – WM_RBUTTONDOWN. После отжатия левой (правой) клавиши функция окна получит код WM_LBUTTONUP (WM_RBUTTONUP). После перемещения курсора мыши функция окна получает код WM_MOUSEMOVE.

Можно получать сообщения от мыши, даже если курсор мыши не находится над рабочей областью окна. Для передачи мыши в монопольное использование окну hWnd вызывают функцию:

HWND SetCapture(HWND hWnd);

Эта функция возвращает дескриптор окна, у которого в монопольном пользовании была мышь, или NULL.

Вызов функции

void ReleaseCapture(void);

отменяет режим монопольного использования.

Значение параметра lParam зависит от кода сообщения.

При поступлении кода WM_MOVE параметр lParam содержит экранные координаты левого верхнего угла рабочей области. Например:

//Координата левого края рабочей области

left = LOWORD(lParam);

//Координата верхнего края рабочей области

top = HIWORD(lParam);

Для кода WM_SIZE параметр lParam несет информацию о ширине сх и высоте cy рабочей области:

cx = LOWORD(lParam); //Ширина рабочей области

cy = HIWORD(lParam); //Высота рабочей области

При поступлении любых сообщений от мыши расстояние курсора мыши от левого края рабочей области равно LOWORD(lParam), а от верхнего края – HIWORD(lParam).

Обратите внимание на описание локальных переменных. Если хотят, чтобы какие-либо переменные сохраняли свои значения до следующего вызова функции окна, то их описывают с приставкой static. Например, если функция окна многократно использует ширину сх и высоту сy рабочей области окна, то их описывают как static.

Вызов функции DefWindowProc означает, что необработанное сообщение возвращают операционной системе. Например, в данном примере не обрабатывают сообщения от мыши (как и многие другие получаемые сообщения). Эти сообщения, тем не менее, передаются функции окна, но она их возвращает операционной системе.

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

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: