Базовые элементы 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…);

…