Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УП01_Окна_Создание приложения Win32.doc
Скачиваний:
4
Добавлен:
01.03.2025
Размер:
486 Кб
Скачать

2.2. Пример регистрации класса окон

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

int RegClass( WNDPROC Proc, LPCTSTR szName)

{

WNDCLASS wc;

wc.style = CS_HREDRAW | CS_VREDRAW;

wc.cbClsExtra = wc.cbWndExtra = 0;

wc.lpfnWndProc = Proc;

wc.hInstance = hInstance;

wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

wc.lpszMenuName = (LPCTSTR)NULL;

wc.lpszClassName = szName;

return RegisterClass(&wc);

}

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

Не используются дополнительные данные:

wc.cbClsExtra = wc.cbWndExtra = 0;

Поле hInstance содержит дескриптор текущего приложения:

wc.hInstance = hInstance;

Функция RegisterClass регистрирует класс в операционной системе. Ее аргументом является адрес подготовленной структуры wc. При успешной регистрации класса она возвращает ненулевое значение, иначе – нуль. Оператор возврата функции RegClass:

return RegisterClass(&wc);

в случае успешной регистрации класса возвращает ненулевое значение, иначе – нуль.

2.3. Функция окна

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

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

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

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

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

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

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

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 означает, что необработанное сообщение возвращают операционной системе. Например, в данном примере не обрабатывают сообщения от мыши (как и многие другие получаемые сообщения). Эти сообщения, тем не менее, передаются функции окна, но она их возвращает операционной системе.

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

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