LEKCII (Лекции), страница 21
Описание файла
Файл "LEKCII" внутри архива находится в папке "Лекции". Документ из архива "Лекции", который расположен в категории "". Всё это находится в предмете "api windows" из 6 семестр, которые можно найти в файловом архиве МГТУ им. Н.Э.Баумана. Не смотря на прямую связь этого архива с МГТУ им. Н.Э.Баумана, его также можно найти и в других разделах. Архив можно найти в разделе "лекции и семинары", в предмете "api windows" в общих файлах.
Онлайн просмотр документа "LEKCII"
Текст 21 страницы из документа "LEKCII"
Прежде, чем выполнять перемещение начала координат, следует определить размеры внутренней области окна. Это можно сделать при обработке сообщения WM_SIZE:
static short cxClient, cyClient;
....
case WM_SIZE:
{
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
....
return 0;
}
Для того чтобы расположить начало координат в левом нижнем углу окна, следует вызвать функцию SetViewportOrg, передав ей новые координаты начала физической системы координат (0,cyClient):
SetViewportOrg(hdc, 0, cyClient);
Полученная в результате система координат показана на рис.
Рис. Метрическая система координат, начало координат находится в левом нижнем углу окна.
Аналогичным образом можно расположить начало системы координат в середине окна, обеспечив возможность использования положительных и отрицательных координат вдоль оси X и Y:
SetViewportOrg(hdc, cxClient/2, cyClient/2);
Рис. Метрическая система координат, начало координат находится в центре окна
Режимы MM_ISOTROPIC и MM_ANISOTROPIC
Режимы отображения MM_ISOTROPIC (изотропный) и MM_ANISOTROPIC (анизотропный) допускают изменение направления осей X и Y, а также изменение масштаба осей координат. В изотропном режиме отображения MM_ISOTROPIC масштаб вдоль осей X и Y всегда одинаковый (т. е. для обоих осей используются одинаковые логические единицы длины). Анизотропный режим MM_ANISOTROPIC предполагает использование разных масштабов для разных осей (хотя можно использовать и одинаковые масштабы).
Для изменения ориентации и масштаба осей предназначены функции SetViewportExt, SetViewportExtEx, SetWindowExt и SetWindowExtEx.
Функция SetWindowExt устанавливает для формулы преобразования координат значения переменных xWinExt и yWinExt:
DWORD WINAPI SetWindowExt(
HDC hdc, // идентификатор контекста отображения
int nXExtent, // значение для xWinExt
int nYExtent); // значение для yWinExt
Функция SetViewportExt должна использоваться после функции SetWindowExt. Она устанавливает для формулы преобразования координат значения переменных xViewExt и yViewExt:
DWORD WINAPI SetViewportExt(
HDC hdc, // идентификатор контекста отображения
int nXExtent, // значение для xViewExt
int nYExtent); // значение для yViewExt
Обе функции возвращают в младшем и старшем слове предыдущие значения соответствующих переменных для оси X и Y.
Приведенные выше формулы можно использовать для установки отношений xViewExt/xWinExt и yViewExt/yWinExt, определяющих масштаб и направление осей координат (направление осей координат зависит от знака этих отношений).
Функции SetWindowExt передаются значения, соответствующие логическому размеру логического окна, в которое будет выполняться вывод, а функции SetViewportExt - реальные ширина и высота реального окна.
Например, нам надо создать систему координат, в которой начало отсчета расположено в левом нижнем углу окна, ось X направлена слева направо, а ось Y - снизу вверх. Высота и ширина должны изменяться от 0 до 32767 (максимально возможное значение, так как для координат используются 16-разрядные числа).
Если требуется получить одинаковый масштаб по осям X и Y, нужно использовать изотропный режим отображения MM_ISOTROPIC.
Приведем фрагмент кода, создающий необходимый режим отображения.
SetMapMode(hdc, MM_ISOTROPIC);
SetWindowExt(hdc, 32767, 32767);
SetViewportExt(hdc, cxClient, -cyClient);
SetViewportOrg(hdc, 0, cyClient);
В изотропном режиме отображения при изменении размеров окна Windows настроит систему координат таким образом, чтобы масштаб по осям X и Y был одинаковый.
Если ширина окна больше высоты, масштаб по горизонтальной оси настраивается таким образом, что логическое окно будет расположено в левой части внутренней области окна.
Рис. Изменение масштаба по горизонтали при увеличении ширины окна в изотропном режиме
Если же высота окна больше его ширины, при использовании изотропного режима отображения логическое окно окажется в нижней части внутренней области окна.
Рис. Изменение масштаба по горизонтали при увеличении высоты окна в изотропном режиме
При использовании анизотропного режима отображения MM_ANISOTROPIC настройка масштаба не выполняется, поэтому логическое окно будет занимать всю внутреннюю поверхность окна при любом изменении размеров этого окна.
Рис. Изменение масштаба по горизонтали при увеличении ширины окна в анизотропном режиме
Рис. Изменение масштаба по горизонтали при увеличении высоты окна в анизотропном режиме
В программном интерфейсе Windows есть новые функции, предназначенные для изменения масштабов осей. Это функции SetViewportExtEx и SetWindowExtEx :
BOOL WINAPI SetViewportExtEx(
HDC hdc, // идентификатор контекста отображения
int nXExtent, // значение для xViewExt
int nYExtent, // значение для yViewExt
SIZE FAR* lpSize); // указатель на структуру SIZE
BOOL WINAPI SetWindowExtEx(
HDC hdc, // идентификатор контекста отображения
int nXExtent, // значение для xWinExt
int nYExtent, // значение для yWinExt
SIZE FAR* lpSize); // указатель на структуру SIZE
От функций SetViewportExt и SetWindowExt эти функции отличаются тем, что старые значения переменных, определяющих масштаб преобразования, записываются в структуру SIZE, указатель на которую передается через параметр lpSize.
Изотропный режим отображения удобно использовать в тех случаях, когда надо сохранить установленное отношение масштабов осей X и Y при любом изменении размеров окна, в которое выводится изображение.
Анизотропный режим удобен в тех случаях, когда изображение должно занимать всю внутреннюю поверхность окна при любом изменении размеров окна. Соотношение масштабов при этом не сохраняется.
Рисование геометрических фигур
Несмотря на то, что в программном интерфейсе GDI имеется функция SetPixel , позволяющая нарисовать один пиксел, не следует думать, что рисование линии или окружности сводится к многократному вызову этой функции. Если бы это было так, процесс рисования занимал бы очень много времени. На самом деле многие из функций рисования выполняются драйвером или даже аппаратурой видеоконтроллера, что значительно ускоряет вывод.
С помощью функции GetDeviceCaps приложение может определить, поддерживает ли драйвер ту или иную функцию рисования.
Первый параметр функции hdc задает контекст устройства, для которого необходимо получить информацию о его возможностях.
Второй параметр iCapability определяет параметр устройства, значение которого необходимо получить.
Приведем список значений для второго параметра функции GetDeviceCaps, с помощью которых можно определить, какие операции рисования выполняет драйвер устройства вывода.
Имя константы | Описание |
LINECAPS | Способности устройства рисовать линии. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать линии различного типа:LC_INTERIORS устройство может закрашивать внутреннюю область;LC_MARKER маркеры;LC_NONE устройство не может рисовать линии;LC_POLYLINE ломаные линии;LC_POLYMARKER линии polymarker;LC_STYLED устройство может рисовать линии с использованием различных стилей (штриховые, пунктирные, штрих пунктирные и т.д.);LC_WIDE широкие линии;LC_WIDESTILED устройство может рисовать широкие линии с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.) |
CURVECAPS | Способность устройства рисовать различные кривые линии и геометрические фигуры. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать различные фигуры:CC_CIRCLES окружности;CC_CHORD сегмент эллипса;CC_ELLIPSES эллипсы;CC_INTERIORS устройство может закрашивать внутреннюю область геометрических фигур;CC_NONE устройство не может рисовать кривые линии и геометрические фигуры;CC_PIE секторы эллипса;CC_ROUNDRECT прямоугольники со скругленными углами;CC_STYLED устройство может рисовать рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т.д.);CC_WIDE широкие рамки;CC_WIDESTYLED устройство может рисовать широкие рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.) |
POLYGONALCAPS | Способности устройства рисовать многоугольники. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать многоугольники различного типа:PC_INTERIORS устройство может закрашивать внутреннюю область;PC_NONE устройство не может рисовать многоугольники;PC_RECTANGLE прямоугольники;PC_SCANLINES устройство может выполнять сканирование линий растра;PC_STYLED устройство может рисовать рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.);PC_WIDE широкие рамки;PC_WIDESTILED устройство может рисовать широкие рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.)PC_WINDPOLYGON многоугольники с заполнением в режиме WINDING |
Для приложения не имеет особого значения, кто именно будет рисовать - видеоконтроллер, драйвер или GDI. Запрос на рисование, например, эллипса, будет выполнен, даже если соответствующая операция не поддерживается драйвером. В последнем случае эллипс будет нарисован самим GDI с использованием более примитивных операций, но процесс рисования займет больше времени.
Современные видеоадаптеры сконструированы таким образом, что большинство основных операций рисования, используемых в операционной системе Windows, выполняются аппаратно. Эти видеоадаптеры иногда называются ускорителями Windows. Скорость рисования для ускорителя Windows может превышать в десятки раз скорость рисования для обычного адаптера VGA или SVGA.
Результат рисования геометрических фигур зависит от установки таких атрибутов контекста, как ширина, цвет и стиль линии (определяются выбранным в контекст отображения пером), способ закраски замкнутых фигур (определяется выбранной в контекст отображения кистью), цвета фона, прозрачностью фона (прозрачный режим TRANSPARENT и непрозрачный режим OPAQUE), режимом рисования, режимом закрашивания, областью ограничения, режимом отображения, т. е. практически от всех атрибутов контекста отображения. Поэтому при описании функций мы будем попутно описывать способы изменения атрибутов контекста отображения, влияющих на результат их выполнения.
Работа с цветовыми палитрами и битовыми изображениями будут рассмотрены позже в отдельных разделах, так как эти вопросы далеко не тривиальны и поэтому заслуживают отдельного обсуждения.
Итак, перейдем непосредственно к описанию функций рисования геометрических фигур.
Рисование точки
Функция рисования точки SetPixel устанавливает цвет точки с заданными координатами:
COLORREF WINAPI SetPixel(
HDC hdc, // контекст отображения
int nXPos, // x-координата точки
int nYPos, // y-координата точки
COLORREF clrref); // цвет точки
Установка первых трех параметров этой функции не должна вызывать у вас никаких затруднений. Параметр hdc определяет контекст отображения, для которого необходимо изменить цвет точки. Параметры nXPos и nYPos определяют координаты точки в системе координат, которая зависит от установленного для контекста hdc режима отображения.