Базовые элементы Windows-приложений. Проект типа Win32 Application, страница 4

UINT wMsgFilterMin,     // ”нижнее” значение диапазона сообщений

UINT wMsgFilterMax);   // «верхнее» значение диапазона сообщений.                      //Если wMsgFilterMin и wMsgFilterMax оба равны 0, проверка                         //принадлежности сообщения диапазону не осуществляется, т.е.                  //обрабатываются все доступные сообщения.

получает сообщение из очереди сообщений потока и помещает его в указанную структуру типа MSG. Когда функция GetMessage() возвращает FALSE (то есть 0), извлекая из очереди потока сообщение WM_QUIT, происходит выход из цикла обработки сообщений.

Замечание: возвращаемое значение может быть TRUE, FALSE, или –1(в случае неудачного завершения, например, если указан invalid handler).

Функция TranslateMessage()

BOOL TranslateMessage( CONST MSG *lpMsg): транслирует сообщения о нажатии “виртуальной” клавиши в символьное сообщение и снова посылает сообщение уже в более “читабельном” виде вызывающему потоку. В таком виде сообщение будет выбрано при следующем вызове GetMessage() и отправлено соответствующему окну.

Функция DispatchMessage()

LONG          DispatchMessage(CONST MSG *lpmsg); передает сообщение оконной процедуре. Возвращаемое значение обычно игнорируется.

Замечание: поскольку основная идея Windows заключается в том, что что приложение не вызывает явно такие функции как оконная процедура, то DispatchMessage() только “указывает” Windows, что сообщение должно быть передано оконной функции соответствующего окна.

..6 Оконная процедура

не вызывается явно! Управление ей передает сама Windows.

LRESULT CALLBACK WndProc(        HWND hWindow,

UINT Message,

WPARAM wParam,

LPARAM lParam);

Ключевое слово CALLBACK определено как

#define CALLBACK    __stdcall

и используется вместо старого FAR PASCAL в таких (callback)процедурах приложения как оконная процедура.

..6.1 DefWindowProc()

В оконной процедуре будут индивидуально обрабатываться только те сообщения, которые Вы захотите обрабатывать сами. Существует оконная процедура обработки сообщений по умолчанию – DefWindowProc(), которой вы можете передать сообщение для стандартной обработки. Процедура вызывается с теми же параметрами, что и оконная процедура. Так что минимальная оконная процедура могла бы выглядеть:

LRESULT CALLBACK WndProc(HWND hWindow, UINT            Message, WPARAM wParam, LPARAM lParam)

{

return DefWindowProc(hWindow, Message,  wParam,  lParam);   //все сообщения, не //обрабатываемые Вашей оконной процедурой, должны //передаваться DefWindowProc() !!!

}

..6.2 Обработка сообщений. Взломщики сообщений.

Взломщики (распаковщики) сообщений содержатся в файле WINDOWSX.H. Этот файл обычно включается сразу же после WINDOWS.H, и он – не что иное, как набор макросов, то есть набор операторов #define. Одно из преимуществ применения макросов – упрощение написания оконных процедур. Если пользоваться оператором switch для сколько-нибудь серьезного приложения, можно превратить оконную процедуру в трудночитаемого «монстра».

Пример использования оператора switch:

LRESULT CALLBACK WndProc(HWND hWindow, UINT            Message, WPARAM wParam, LPARAM lParam)

{

switch(Message)

{

case WM_DESTROY:

PostQuitMessage(0);

return 0;

case WM_PAINT:

//обработка сообщения

case WM_SIZE:

//обработка сообщения

…//обработка других сообщений

default:                                    return DefWindowProc(hWindow, Message,  wParam,  lParam);

}

}

Взломщики сообщений дисциплинируют программиста, заставляя разбивать оператор switch на отдельные функции – по одной на каждое сообщение. Это значительно улучшает структуру кода:

LRESULT CALLBACK WndProc(HWND hWindow, UINT            Message, WPARAM wParam, LPARAM lParam)

{

switch(Message)

{

HANDLE_MSG(hWindow, WM_DESTROY, My_OnDestroy);

HANDLE_MSG(hWindow, WM_DESTROY, My_OnPaint);

HANDLE_MSG(hWindow, WM_DESTROY, My_OnSize);

HANDLE_MSG(hWindow, WM_…, My_ On…);