При выводе текста или графики в рабочую область окна приложения необходимо учитывать следующие правила:
· Экран - разделяемый ресурс, поэтому приложение «не знает» заранее размер пользовательской области.
· Размер области не остается неизменным в процессе работы программы, поэтому для вывода в окно, если требуется знать размеры окна , их нужно определять при каждом выводе.
· Поскольку не программа управляет данными, а сообщения управляют окнами с определенными функциями, то приложение не знает заранее в какой момент времени будет происходить вывод.
· Если пользователь приложения минимизирует окно, а затем снова сохраняет окно , то приложение должно обновить изображение.
· Если рабочая область перекрывается окном другого приложения, а затем освобождается, то требуется также обновить приложение.
· Если требуется перерисовать (обновить) окно немедленно, например, это требуется самому приложению при создании нового окна или при выводе изображения, то сообщение направляется не в очередь приложения, а непосредственно передается в функцию окна приложения. Для этого используется функция Update Window ().
«Общение» с устройствами: дисплеем, принтером, плоттером и другими устройствами вывода, осуществляется функциями GDI (Graphics Device Interface).
При работе с этими функциями приложение оперирует не с адресом видеопамяти или порта компьютера, а со стандартизованным описанием характеристик устройства - контекстом устройства (Device Context).
Контекст устройства - это структура данных, описывающая геометрические и др.
Контекст устройства - специальные параметры устройства.
Контекст устройства - создается и поддерживается Windows.
Контекст устройства - это «паспорт» рабочей области (окна, принтера и т.д.).
Контекст устройства - размещается в перемещаемом сегменте памяти, и функции GDI используют не физический адрес памяти, а дескриптор сегмента.
Обновление рабочей области возлагается на само приложение.
Когда Windows требуется, чтобы приложение обновило содержимое рабочей области окна, в очередь приложения помещается сообщение WM_PAINT.
Windows отслеживает координаты той части рабочей области, которая должна быть обновлена.
Для каждого окна Windows поддерживает «структуру отрисовки», в которой хранятся :
1) внутренние данные;
2) координаты измененной области.
Структура отрисовки PAINTSTRUCT описана в файле windows.h:
typed struct tag PAINTSTRUCT
{ HDC hDC; // копия контекста устройства;
BOOL fErase; // будет или нет перерисовываться фон;
RECT rcPaint; // область отрисовки - прямоугольник
BOOL fRestore;
BOOL fincUpdate; > резервируется Windows
BYTE rgbReserved [16];
} PAINTSTRUCT;
RECT rcPaint; // структурная переменная, задающая координаты области отрисовки
typedtf struct
{ rcPaint.left; // X - левого верхнего угла
rcPaint.right; // X - правого нижнего угла
rcPaint.top; // Y - верхнего левого угла
rcPaint.bottom // Y - нижнего правого угла
} RECT;
События, которые портят содержимое рабочей области окна, вызывают изменение координат такой области, а не само сообщение WM_PAINT.
Сообщение WM_PAINT помещается Windows в очередь приложения в том случае, когда в рабочей области окна есть измененная область и в очереди приложения нет других сообщений.
Это означает, что сообщение от клавиатуры и мыши обладают большим приоритетом, чем сообщение WM_PAINT (перерисовать изображение).
Например, если пользователь мышью выбирает место, то это сообщение сразу помещается в очередь приложения, и отрабатывается, т.е. действия пользователя имеют наивысший приоритет.
Для вывода информации в рабочую область необходимо :
· Создать запрос о создании контекста устройства;
· Использовать операции вывода;
· Освободить контекст устройства.
Получение контекста устройства зависит от того, какое сообщение обрабатывается.
Если обрабатывается сообщение WM_PAINT, то необходим и адрес структуры отрисовки PAINTSTRUCT. Для этого служит функция BeginPaint():
HDC DC = BeginPaint (hWnd, lpPaint);
где DC - адрес контекста устройства;
hWnd - дескриптор окна;
lpPaint - адрес переменной типа PAINTSTRUCT.
По окончании отрисовки от DC необходимо отказаться функцией:
EndPaint (hWnd, lpPaint);
Прямоугольник отрисовки является также областью отсечения, т.е. функции GDI не будут ображать ничего вне прямоугольника, заданного rcPaint.
Если приложение не отрабатывает сообщение WM_PAINT, то оно передается Windows функцией DefWindowProc() для стандартной обработки.
Если сообщение WM_PAINT для вывода в окно пользователя неудобно, например, необходимо реализовать свой алгоритм отрисовки, то можно создать свое сообщение, например, WM_DRAW. При этом для получения дескриптора устройства и освобождения дескриптора устройства следует использовать функции GetDC() и ReleaseDC();
HDC DC = GetDC (hWnd);
.
.
ReleaseDC (hWnd, DC);
Поскольку алгоритм обновления сообщения WM_PAINT в этом случае не используется, то структура отрисовки не нужна, и необходим только DC.