Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование в Windows API. Учебное пособие

.pdf
Скачиваний:
1
Добавлен:
12.08.2026
Размер:
752 Кб
Скачать

объекты GDI. Такие действия необходимо выполнять по строгим правилам, указанным ниже. Если программа использует большое количество контекстов и объектов GDI (сложный специализированный ГПИ), к проектированию схем запроса / освобождения контекстов и создания / удаления объектов следует подойти особенно тщательно.

При работе многооконного ГПИ одни окна оказываются перекрытыми другими окнами. Переключение видимости и расположения окна, вывод его на передний план может выполняться пользователем через стандартные команды управления окном или просто прикладной программой. Если программа выполняет вывод информации в окно собственного класса, она периодически (в зависимости от происходящих событий) получает от ОС оповещения о том, что часть окна была повреждена и программа должна восстановить изображение в данном окне. Это выполняется с помощью сообщения WM_PAINT, которое означает необходимость обновления всей или части клиентской области окна.

Общий порядок действий программы, выполняющей графический вывод на экран, выглядит следующим образом:

1.Создание контекста графического устройства с помощью функций BeginPaint(…) или GetDC(…).

2.Создание инструментов графического вывода (объектов GDI - перьев, кистей, шрифтов и др.) c помощью функций CreatePen(…), CreateSolidBrush(…) и др.

3.Присваивание графическому объекту статуса текущего с помощью функции SelectObject(…).

41

4.Выполнение отрисовки графических объектов с помощью функций рисования графических примитивов.

5.По завершении отрисовки удаление ранее созданных графических объектов с помощью функции DeleteObject(…) и освобождение контекста графического вывода с помощью функций EndPaint(…)

или ReleaseDC(…).

5.1. Правила обработки сообщения WM_PAINT. Функции API для подготовки контекста устройства.

Типичная функция-обработчик сообщения WM_PAINT выглядит следующим образом:

BOOL MainOnPaint (HWND hwnd)

{

//структура с информацией о контексте

//и повреждённой области окна

PAINTSTRUCT ps;

//подготовка к выполнению рисования

HDC hdc = BeginPaint(hwnd, &ps);

//ВЫЗОВ ФУНКЦИЙ ГРАФИЧЕСКОГО ВЫВОДА

. . .

//завершение рисования

EndPaint (hwnd, &ps); return TRUE;

} // MainOnPaint

Функция BeginPaint подготавливает окно к выполнению вывода и заполняет структуру типа PAINTSTRUCT данными о повреждённой области окна и контексте:

42

HDC BeginPaint (HWND hWnd, LPPAINTSTRUCT lpPaint);

hWnd

Дескриптор окна, требующего перерисовки. lpPaint

Указатель на структуру PAINTSTRUCT, которая получает данные о требуемой перерисовке.

Возвращаемое значение:

при успешном завершении: значение дескриптора контекста клиентской области окна;

при ошибке: NULL.

Функция автоматически устанавливает область отсечения контекста таким образом, что приложение получает возможность выполнения вывода только в повреждённую область, исключая области окна, не требующие перерисовки. Если в классе окна указана кисть фона, BeginPaint выполняет закраску повреждённой области. Функция BeginPaint должна вызываться только при обработке сообщения WM_PAINT, обработка сообщения должна обязательно завершаться вызовом функции EndPaint.

Функция EndPaint извещает ОС о завершении вывода в окно:

BOOL EndPaint (HWND hWnd,

CONST PAINTSTRUCT *lpPaint);

hWnd

Дескриптор окна, в котором была выполнена перерисовка.

lpPaint

Указатель на структуру PAINTSTRUCT, которая содержит данные о требуемой перерисовке, полученные функцией BeginPaint.

Возвращаемое значение: всегда ненулевое.

43

Функция указывает ОС, что текущее сообщение WM_PAINT обработано, а также освобождает полученный ранее функцией BeginPaint контекст устройства. Функция EndPaint должна вызываться только при обработке сообщения WM_PAINT, обработка сообщения должна обязательно начинаться вызовом функции BeginPaint. Если вызов EndPaint не выполнить, ОС будет повторно передавать приложению сообщения WM_PAINT о последней повреждённой области.

Структура PAINTSTRUCT содержит следующие поля:

hdc

Дескриптор контекста устройства, на которое выполняется вывод.

fErase

Флаг требования закраски фона. Это значение ненулевое, если приложению рекомендуется стирать фон. Приложение может откликаться для стирания фона, если в классе окна не указана кисть закраски фона. См. описание поля hbrBackground структуры

WNDCLASSEX. rcPaint

Указатель на структуру типа RECT, которая содержит координаты прямоугольника, внутри которого запрашивается перерисовка.

fRestore

Зарезервировано ОС для внутреннего использования. fIncUpdate

Зарезервировано ОС для внутреннего использования. rgbReserved

Зарезервировано ОС для внутреннего использования.

Графический вывод в окно может выполняться и без использования механизма обработки сообщения WM_PAINT. Дескриптор контекста устройства (окна)

44

может быть в любой момент получен с помощью функции GetDC, а освобождён функцией ReleaseDC:

BOOL Draw (HWND hwnd)

{

// подготовка к выполнению рисования

HDC hdc = GetDC(hwnd);

//ВЫЗОВ ФУНКЦИЙ ГРАФИЧЕСКОГО ВЫВОДА

...

// завершение рисования

ReleaseDC (hwnd, hdc); return TRUE;

} // Draw

Функция GetDC извлекает дескриптор контекста клиентской области окна:

HDC GetDC (HWND hWnd);

hWnd

Дескриптор окна, дескриптор контекста которого должен быть получен. Если значение параметра равно NULL, возвращается контекст всего экрана. Если значение параметра равно NULL, функция получает контекст первичного дисплея.

Возвращаемое значение:

при успешном завершении: значение дескриптора контекста клиентской области окна;

при ошибке: NULL.

Полученный с помощью данной функции контекст после завершения рисования должен быть освобождён с помощью функции ReleaseDC.

45

int ReleaseDC (HWND hWnd, HDC hDC);

hWnd

Дескриптор окна, контекст которого должен быть освобождён.

hDC

Дескриптор освобождаемого контекста.

Возвращаемое значение:

при успешном освобождении контекста: 1;

если контекст не был освобождён: ноль.

Действие данной функции зависит от конкретного типа контекста: освобождаются только общие контексты и контексты окон; классовые и собственные контексты не освобождаются. Освобождаемый данной функцией контекст должен быть ранее получен с помощью функций

GetDC или GetWindowDC.

5.2 Правила использования объектов GDI. Некоторые функции API для работы с объектами GDI.

Приложение может использовать большое количество объектов GDI. Описание каждого объекта GDI хранится ОС в специальных таблицах. Дескрипторы объектов GDI доступны только процессу, который их создал. Если приложение в ходе выполнения использует несколько объектов GDI с заранее известными свойствами (например, 20 перьев, 10 кистей, 4 шрифта), предпочтительно создать их при запуске приложения и удалить при завершении. Однако если состав объектов GDI не может быть полностью определён изначально, создавать и удалять рабочие объекты приходиться

динамически

в

ходе

выполнения,

например,

непосредственно

 

в блоке

обработки

сообщения

 

 

46

 

 

WM_PAINT, чтобы не допустить переполнение системной таблицы объектов GDI процесса.

В каждый момент времени контекст устройства имеет набор активных (текущих) объектов GDI, по одному каждого типа (1 перо, 1 кисть и т.д.). Активным называется объект, с использованием которого выполняется операция графического вывода. Например, при рисовании линии используется активное перо, для рисования заполненного прямоугольника – активные перо и кисть.

Функция SelectObject устанавливает активный объект GDI определённого типа для указанного контекста:

HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj);

hdc

Дескриптор контекста устройства. hgdiobj

Дескриптор объекта, который должен быть выбран. Функции, с помощью которых объект может быть создан, приведены в таблице 5.1.

Возвращаемое значение:

при успешном завершении:

если объект не является областью: дескриптор объекта того же типа, который был активным ранее;

если объект является областью:

Значение

Описание

 

Область состоит из

SIMPLEREGION

единственного

 

прямоугольника.

COMPLEXREGION

Область состоит из

нескольких прямоугольников.

 

NULLREGION

Область пустая.

 

47

при ошибке:

если объект не является областью: NULL;

если объект является областью: GDI_ERROR.

Приложение должно всегда восстанавливать состояние контекста устройства, т.е. после завершения рисования выделять в контексте все объекты, активные до начала использования контекста приложением. Приложение не может выбрать битовое изображение (bitmap) более чем в одном контексте одновременно.

Таблица 5.1. Объекты GDI и функции API, предназначенные для их создания

Объект GDI

Функции API

Битовое

CreateBitmap

CreateBitmapIndirect

изображение

CreateCompatibleBitmap

(bitmap)

CreateDIBitmap

 

CreateDIBSection

 

CreateBrushIndirect

 

CreateDIBPatternBrush

Кисть (brush)

CreateDIBPatternBrushPt

CreateHatchBrush

 

 

CreatePatternBrush

 

CreateSolidBrush

Шрифт (font)

CreateFont

CreateFontIndirect

 

Перо (pen)

CreatePen

CreatePenIndirect

 

 

CombineRgn

 

CreateEllipticRgn

Область

CreateEllipticRgnIndirect

(region)

CreatePolygonRgn

 

CreateRectRgn

 

CreateRectRgnIndirect

48

Функция DeleteObject удаляет указанный неактивный объект GDI:

BOOL DeleteObject (HGDIOBJ hObject);

hObject

Дескриптор логического пера, кисти, шрифта, битового изображения, области или палитры.

Возвращаемое значение:

при успешном завершении: ненулевое значение;

если указанный дескриптор некорректный или активен в контексте: ноль.

Данная функция удаляет логическое перо, кисть, шрифт, битовое изображение, область или палитру, освобождая все системные ресурсы, связанные с объектом. Рекомендуется в процессе выполнения удалять объекты, которые в дальнейшем не потребуются.

Функция GetCurrentObject определяет дескриптор активного в указанном контексте объекта GDI определённого типа:

HGDIOBJ GetCurrentObject (HDC hdc,

UINT uObjectType);

hdc

Дескриптор контекста устройства. uObjectType

Код типа активного объекта GDI (таблица 5.2).

Возвращаемое значение:

при успешном завершении: дескриптор активного объекта GDI;

при ошибке: NULL.

49

Таблица 5.2. Коды объектов GDI

Значение

Описание

OBJ_BITMAP

Битовое

 

изображение.

OBJ_BRUSH

Кисть.

OBJ_COLORSPACE

Цветовое

 

пространство.

OBJ_FONT

Шрифт.

OBJ_PAL

Палитра.

OBJ_PEN

Перо.

Функция GetStockObject получает дескриптор готового к использованию системного объекта GDI указанного типа:

HGDIOBJ GetStockObject (int fnObject);

fnObject

Код стандартного системного объекта GDI (табл.5.3).

Возвращаемое значение:

при успешном завершении: дескриптор системного объекта GDI;

при ошибке: NULL.

Системные объекты не требуется удалять после завершения использования в приложении, удаление таких объектов с помощью функции DeleteObject не вызовет никаких действий.

Таблица 5.3.

Коды предопределённых системных объектов GDI

Значение

Описание

BLACK_BRUSH

Чёрная кисть.

 

Тёмно-серая кисть. Рекомендуется

DKGRAY_BRUSH

использовать только в окнах классов,

имеющих стили CS_HREDRAW и

 

 

CS_VREDRAW.

 

50

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]