Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

область (region)

Читайте также:
  1. А.4. Перечень ограничений, влияющих на область применения
  2. Автономная область, автономный округ
  3. Анализ комплекса маркетинга субъекта РФ: Костромская область
  4. Белгородская область
  5. Брянская область
  6. ВЫПАРИВАНИЕ И ОБЛАСТЬ ЕГО ПРИМЕНЕНИЯ. ИЗМЕНЕНИЕ СВОЙСТВ РАСТВОРА ПРИ СГУЩЕНИИ.
  7. Генетическая инженерия и область ее применения в биотехнологии

- используются для задания clipping regions - областей отсечения, вне которых вывод графики блокируется.

Работа с графическими объектами производится с помощью их дескрипторов (handles) - HDC, HPEN, HBRUSH, HFONT и т.д. Создание и удаление объектов производится с помощью соответствующих функций - например, объект pen создается с помощью CreatePen, удаляется с помощью DeleteObject. Режимы, задающиеся через графические объекты, переключаются с помощью создания новых объектов и указания контексту (DC) использовать их для вывода графики. Это делается помощью функции SelectObject:

//hdc - дескриптор контекста устройства

HPEN hWhitePen, hBlackPen, hOldPen;

HBRUSH hBlackBrush, hOldBrush;

 

hWhitePen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));

hBlackPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));

hBlackBrush = CreateSolidBrush(RGB(0, 0, 0));

 

 

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

hOldPen = SelectObject(hdc, hWhitePen);

MoveTo(hdc, 10, 10);

LineTo(hdc, 100, 10);

LineTo(hdc, 100, 100);

LineTo(hdc, 10, 100);

LineTo(hdc, 10, 10);

 

 

// нарисовать черную окружность

SelectObject(hdc, hBlackPen);

hOldBrush = SelectObject(hdc, hBlackBrush);

Ellipse(hdc, 10, 10, 100, 100);

 

 

// вернуть старый объекты pen и brush в DC

SelectObject(hdc, hOldPen);

SelectObject(hdc, hOldBrush);

 

 

// освободить ресурсы

DeleteObject(hWhitePen);

DeleteObject(hBlackPen);

DeleteObject(hBlackBrush);

 

При выборе нового объекта через SelectObject в качестве возвращаемого значения передается дескриптор объекта, бывшего в использовании в DC раньше. Нужно иметь ввиду, что все создаваемые объекты нужно не забывать удалять их после использования. Более того, сам DC всегда создается с некоторыми объектами по умолчанию и при использовании определенных пользователем объектов через SelectObject нужно в конце работы произвести select объектов, которые были в DC изначально (см. пример выше).

2.3 Как рисовать в окно приложения?

Для того чтобы выводить графику в определенное окно вашего приложения нужно сделать буквально следующее:

Получить дескриптор DC, связанный с окном, в которое вы собираетесь рисовать с помощью функции GetDC(). Нарисовать все, что вы хотите, с помощью функций DC и в конце "освободить" контекст с помощью функции ReleaseDC().

Пример:

//hwnd - дескриптор окна, в которое будем рисовать

HDC hdc;

 

hdc = GetDC(hwnd);

if ¯(hdc)

{

// рисуем что требуется

...

 

// освобождаем контекст

ReleaseDC(hwnd, hdc);

}

else

{

// обработка ошибки получения контекста

}

Иным образом производится получение/освобождение дескриптора DC при обработке сообщения WM_PAINT - об этом в следующем разделе.

2.4 Когда рисовать в окно приложения? WM_PAINT - что это?

При выводе графики в Windows есть некоторая тонкость, не всегда очевидная новичкам в программировании под среды с графическим интерфейсом. Казалось бы, если нужно что-то отрисовать в окне - получай его контекст и рисуй. Но не все так просто. Стоит свернуть окно или закрыть его часть другим окном - все, что было нарисовано, пропадет.

Дело в том, что Windows не хранит содержимое клиентской части окна. К клиентской части окна относится ВСЕ, кроме заголовка окна и управляющих элементов (controls): меню, панелей инструментов (toolbar), кнопок и т.д. Приложение само должно позаботиться о том, чтобы отрисовывать свои данные в клиентской области, Windows лишь посылает ему уведомление когда это нужно сделать. Делается это посредством посылки окну сообщения WM_PAINT.

Все необходимые действия по полной перерисовке информации клиентской части окна должны вызываться при обработке события WM_PAINT. Важным понятием при обработке этого сообщения является invalid rectangle. Windows определяет invalid rectangle как наименьшую прямоугольную часть окна, которая была "испорчена" и должна быть перерисована заново. Когда система обнаруживает invalid rectangle в клиентской области окна, она генерирует сообщение WM_PAINT. В ответ на сообщение окно может получить структуру PAINTSTRUCT, которая среди прочего содержит координаты invalid rectangle. Это может пригодиться, если есть желание перерисовывать не все окно, а только ту область, что требуется.

При обработке WM_PAINT должна быть вызвана функция BeginPaint, которая снова делает invalid rectangle `нормальным'. Также BeginPaint возвращает дескриптор DC, который должен быть использован для перерисовки клиентской части окна. Нужно иметь в виду, что при обработке WM_PAINT дескриптор DC окна должен быть получен именно с использованием BeginPaint, а освобожден EndPaint, в то время как во всех других случаях отрисовки нужно использовать другие функции (например, GetDC/ReleaseDC). Если invalid rectangle не делается "нормальным" во время обработки этого события (с помощью BeginPaint или ValidateRect), Windows будет слать WM_PAINT окну постоянно.

Пример обработки WM_PAINT:

//hwnd - дескриптор окна, в которое будем рисовать

HDC hdc;

PAINTSTRUCT PaintStruct;

 

hdc = BeginPaint(hwnd, &PaintStruct);

if ¯(hdc)

{

// рисуем что требуется

...

 

// освобождаем контекст

EndPaint(hwnd, &PaintStruct);

}

else

{

// обработка ошибки получения контекста

}

2.5 Как БЫСТРО рисовать в Device Context?

С каждым DC, предназначенным для графического вывода, связан графический объект bitmap (растровое изображение), который хранит массив пикселей, выводимых на устройство. Для того, чтобы быстро переместить графические данные с одного контекста на другой, можно не повторять все действия по отрисовке, а просто скопировать данные связанного с контекстом bitmap. Для этого даны специальные функции быстрого копирования пикселей (BitBlt, StretchBlt).

Зачем это может быть нужно? Дело в том, что если вы часто рисуете достаточно сложную изменяющуюся картинку средствами GDI, сами операции рисования начинают занимать заметное для пользователя время и возникает неприятный эффект мерцания изображения - когда часть картинки уже перерисовалась, а часть еще осталась старой. Для того, чтобы избежать подобного эффекта новая картинка может создаваться в виртуальном DC в памяти, и потом быстро переносится на экран функциями копирования bitmap.

Пример:

// hdc - дескриптор контекста устройства для вывода

// iWidth, iHeight - размеры окна вывода

HDC hMemDC;

 

hMemDC = CreateCompatibleDC(hdc);

if ¯(hMemDC)

{

// рисуем все что требуется

...

 

// быстро копируем результат отрисовки

BitBlt(hdc, 0, 0, iWidth, iHeight, hMemDC, 0, 0, SRCCOPY);

// освобождаем контекст

DeleteDC(hMemDC);

}

else

{

// обработка ошибки получения контекста

}

2.6 Как загрузить и вывести на экран изображение?

Пользуясь базовыми функциями WinAPI, это к сожалению не так-то просто. Никаких встроенных функций по загрузке изображения из bmp файла не предусмотрено, поэтому требуется самостоятельно писать функцию загрузки. Эта функциональность уже тысячу раз реализована, одна из реализаций предлагается вам в примере, который прилагается к данному тексту.

В принципе, если вы не собираетесь выводить загружаемое растровое изображение на экран (а, скажем, только обрабатывать и сохранять), то его можно хранить в совершенно произвольных собственных структурах данных. Однако, если вы хотите иметь возможность быстро вывести ваше изображение на экран, или рисовать в нем средствами GDI, придется хранить его определенным образом. Потребуется создать графический объект bitmap, соответствующий параметрам файла bmp, и загрузить в него данные из файла (пиксели). Пример, как это сделать, содержится в классе DSimpleBitmap в примере MFC_GML3.

Для того, чтобы уметь быстро выводить загруженное изображение на экран, требуется сделать следующее - с помощью функции SelectObject привязать к созданному заранее memory DC загруженный bitmap (вместо default bitmap, создающегося вместе с контекстом) и затем функцией копирования битов вывести в дисплейный контекст, связанный с вашим окном. Пример:

 

// hdc - дескриптор контекста устройства для вывода

// iWidth, iHeight - размеры окна вывода

// hBitmap - дескриптор изображения для отрисовки

HDC hMemDC;

HBITMAP hOldBitmap;

 

hMemDC = CreateCompatibleDC(hdc);

if (hMemDC)

{

// рисуем все что требуется

hOldBitmap = SelectObject(hMemDC, hBitmap);

// копируем биты

BitBlt(hdc, 0, 0, iWidth, iHeight, hMemDC, 0, 0, SRCCOPY);

// возвращаем старый bitmap

SelectObject(hMemDC, hOldBitmap);

// освобождаем контекст

DeleteDC(hMemDC);

}

else

{

// обработка ошибки получения контекста

}

 

Не забудьте уничтожить все временные объекты, которые создавались (в данном случае - это memory DC). Не забудьте также перед тем как будете уничтожать memory DC, выбрать в него (через SelectObject) объект bitmap, который был создан вместе с контекстом, в противном случае произойдет утечка ресурсов.

2.7 Как нарисовать что-либо на изображении?

Есть как минимум два способа. Первый - это получить указатель на пиксели растрового изображения (вариант как это сделать см. секцию 4.1) и менять их напрямую. Второй - это рисовать на изображении с помощью функций GDI. Для реализации второго варианта нужно создать DC, связать с ним bitmap, на котором хотите рисовать, и затем использовать стандартные функции вывода графики. Пример:

// hdc - дескриптор некоторого контекста устройства

// hBitmap - дескриптор изображения

HBITMAP hOldBitmap;

// связываем bitmap с контекстом

hOldBitmap = SelectObject(hdc, hBitmap);

// рисуем круг

Ellipse(hdc, 10, 10, 100, 100);

// возвращаем старый bitmap

SelectObject(hdc, hOldBitmap);

Имейте в виду, объект bitmap может быть одновременно связан только с одним DC.

 


Дата добавления: 2015-11-14; просмотров: 36 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Graphics Device Interface и Device Context| Поступление товара.

mybiblioteka.su - 2015-2024 год. (0.014 сек.)