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

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

}

}

С другой стороны, макросы решают и другую проблему, связанную с обработкой сообщений: дело в том, что у каждого сообщения есть параметры wParam и lParam, смысл которых зависит от типа сообщения, а программист должен если не выучить наизусть, что именно он получает в wParam и lParam для каждого конкретного сообщения, то по крайней мере каждый раз искать эту информацию в справочной системе. Если же Вы используете макросы, Вам не придется “вручную” распаковывать параметры! Достаточно заглянуть в файл WINDOWSX.H, найти макрос для требуемого типа сообщения - HANDLE_WM_СООБЩЕНИЕ и объявить Ваш обработчик так, как это указано в подсказке-комментарии. Например для сообщения WM_SIZE:

Фрагмент из файла WINDOWSX.H

/* void Cls_OnSize(HWND hwnd, UINT state, int cx, int cy) */

#define HANDLE_WM_SIZE(hwnd, wParam, lParam, fn) \

((fn)((hwnd), (UINT)(wParam), (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam)), 0L)

#define FORWARD_WM_SIZE(hwnd, state, cx, cy, fn) \

(void)(fn)((hwnd), WM_SIZE, (WPARAM)(UINT)(state), MAKELPARAM((cx), (cy)))

Объявление Вашего обработчика:

void My_OnSize(HWND hwnd, UINT state, int cx, int cy)

{

}

Обратите внимание на второй макрос, определенный для этого же сообщения – FORWARD_WM_*. Он проделывает операцию, обратную первому макросу – принимает «распакованные» параметры, восссздает из них оригинальные wParam и lParam и передает из в первозданном виде указанной процедуре. Обычно это бывает востребовано при передаче параметров процедуре обработки сообщений по умолчанию или же передачи параметров функциям SendMessage() и PostMessage().

Объединяет все взломщики еще один макрос:

#define HANDLE_MSG(hwnd, message, fn)    \

case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))

,который освобождает Вас от длинного оператора case и необходимости возврата из оконной процедуры значения. HANDLE_MSG осуществляет синтаксический анализ параметров, ассоциированных с любым сообщением, и передает их в отдельную функцию типа classname_OnDestroy().

Сравните:

switch(Message)

{

HANDLE_WM_DESTROY(hwnd, wParam, My_OnDestroy);          

............................

}

и

switch(Message)

{

HANDLE_MSG(hwnd, WM_DESTROY, My_OnDestroy);   

............................

}

..7 Сообщение WM_PAINT

-одно из основных сообщений Windows. Посылается в оконную процедуру всякий раз, когда требуется изменить содержимое рабочей области (client area. Замечание: эта часть окна доступна для Вашего творчества, в то время как Windows “заботится” об остальной части). Вам же следует обеспечить «рисование» посредством “наполнения” обработчика сообщения WM_PAINT.

Шаблон обработчика:

void My_OnPaint(HWND hwnd)

{

PAINTSTRUCT PaintStruct;

HDC PaintDC = BeginPaint(hwnd, &PaintStruct);  //устанавливает контекст устройства для окна. //Рисовать Вы можете только в контексте устройства! Функция //BeginPaint() вызывается только в обработчике сообщения //WM_PAINT !!!

.....рисование......

EndPaint(hwnd, &PaintStruct);  //освобождает контекст

}

Установка фона для вывода:

для текста, hatch – кистей...

int SetBkMode(     HDC hdc,

int iBkMode); // OPAQUE или TRANSPARENT

Вывод текста:

BOOL TextOut(     HDC hdc,

int nXStart,

int nYStart,

LPCTSTR lpString,

int cbString);                  //количество символов в строке

int DrawText(        HDC hDC,

LPCTSTR lpString,

int nCount,   //если равно –1, то Windows сама вычислит длину строки в символах

LPRECT lpRect,    //область внутри которой будет выведена строка

UINT uFormat);     //флаги - как будет выведена строка (группируются по                                                                           //логическому или)

Некоторые значения uFormat:

DT_SINGLELINE, DT_CENTER, DT_VCENTER

..8 Рисование вне обработчика сообщения WM_PAINT.