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);
............................
}
-одно из основных сообщений 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
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.