Операционная система Windows 95 для программиста



    d8ef8794     

Обработка 32-разрядных сообщений - часть 2


#define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp) #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp) #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp) #define GET_WM_COMMAND_MPS(id, hwnd, cmd) \ (WPARAM)MAKELONG(id, cmd), (LONG)(hwnd)

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

Предположим, нам надо организовать обработку сообщений WM_CREATE и WM_LBUTTONDOWN . Мы готовим две функции с именами WndProc_OnCreate и WndProc_OnLButtonDown, которые будут заниматься обработкой этих сообщений:

BOOL WndProc_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct); void WndProc_OnLButtonDown(HWND hWnd, BOOL fDoubleClick, int x, int y, UINT keyFlags);

Имена функций не играют никакой роли, однако Microsoft рекомендует составлять их из префикса имени функции окна (например, WndProc) с добавлением строки _On и названия сообщения, в котором удален префикс WM_.

Затем в функции окна мы используем макрокоманду HANDLE_MSG , указывая ей в качестве первого параметра идентификатор окна, в качестве второго - номер сообщения и, наконец, в качестве третьего - имя функции, которая будет обрабатывать сообщение:

LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { HANDLE_MSG(hWnd, WM_CREATE, WndProc_OnCreate); HANDLE_MSG(hWnd, WM_LBUTTONDOWN, WndProc_OnLButtonDown); default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } }

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

Следует, однако, заметить, что для работы с макрокомандой HANDLE_MSG вы должны использовать в качестве имен для последних двух параметров функции WndProc имена wParam и lParam (только эти имена).

Как выглядит функция обработчика сообщения, вызываемая макрокомандой HANDLE_MSG?

Так же, как и обычная функция, за одним исключением - она должна оканчиваться вызовом макрокоманды FORWARD_<имя сообщения> в операторе return (даже если функция имеет тип void):

void WndProc_OnLButtonDown(HWND hWnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) { ... return FORWARD_WM_LBUTTONDOWN(hWnd, fDoubleClick, x, y, keyFlags, DefWindowProc); }

Но при обработке сообщения WM_CREATE вы должны в случае успешной инициализации данных окна вернуть значение TRUE, иначе окно так и не будет создано:

BOOL WndProc_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct) { ... return TRUE; }

Вы можете создать перечисленные выше макрокоманды и для обработки собственных сообщений, взяв за основу определения из файла windowsx.h.

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

#pragma warning(disable: 4098)




Содержание  Назад  Вперед