70736

ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ЭВМ И СИСТЕМ

Книга

Информатика, кибернетика и программирование

Устройство отображения описывается структурой данных типа HDC которая называется контекстом отображения. В этой структуре хранятся различные характеристики устройства отображения контекст устройства и набор инструментов для рисования выбранных в контекст по умолчанию.

Русский

2014-10-26

154.5 KB

0 чел.

МИНИСТЕРСТВО ОБЩЕГО И ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ

РОССИЙСКОЙ ФЕДЕРАЦИИ

ВОЛГОГРАДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

КАФЕДРА   ЭВМ И СИСТЕМ

ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ЭВМ И СИСТЕМ

Методические  указания к лабораторным работам

Часть  III

Волгоград

2000

УДК 681.31

ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ЭВМ И СИСТЕМ. Методические  указания к лабораторным работам. Часть III /Cост. Деревенсков С.О.;  Волгоград.гос.техн.ун-т.- Волгоград, 2000. – 26 с.

    Содержатся  сведения, необходимые для изучения студентами основ программирования в API WIN32 для операционных систем Windows95 и Windows NT, архитектуры приложений WIN32, основ взаимодействия приложения с операционной системой, создания приложений с использованием интерфейса графических устройств GDI. Приведены примеры выполнения лабораторных работ и варианты заданий к лабораторным работам.

    Предназначены для  студентов,  обучающихся по направлению 5528  "Информатика и вычислительная техника" и  специальности 2201 "Вычислительные машины, комплексы, системы и сети"  всех форм обучения.

   Библиогр. - 5 назв. 

   

   Рецензент  Игнатьев А.Н.

   Печатается  по  решению  редакционно-издательского совета Волгоградского государственного технического университета

                                       

©           Волгоградский

государственный

технический                                                                                      

университет, 2000

3

Лабораторная работа N 4

Интерфейс графических устройств GDI

 Цель работы: изучение основных приемов программирования графического интерфейса пользователя с использованием интерфейса графических устройств GDI.

 Основные сведения

Интерфейс графических устройств (Graphics  Device  Interface - GDI)  предназначен  для  взаимодействия  приложений  Windows  с  графическими  устройствами,  такими  как  видеомонитор,  принтер  или  плоттер.  Приложения  Windows  работают  с  логическими  устройствами  вывода,  которые  не  зависят  от  аппаратуры  и  обладают  практически  неограниченными  возможностями.  Реализованный  в  виде  библиотеки  DLL  интерфейс  GDI  является  промежуточным  звеном  между  приложением  и  драйвером  конкретного  физического  устройства.  Для  вывода  текста  или  графического  изображения  на  экран  видеомонитора  или  принтер  приложение  вызывает  одну  из  функций  GDI.  Выполняя  запрос  приложения,  GDI  обращается  к  драйверу  соответствующего  устройства  вывода.  В  процессе  выполнения  запроса  GDI  и  драйвер учитывают  ограниченные  возможности  физического  устройства  вывода  и  его  аппаратные  особенности. Подобная  организация  вывода  на  устройство  освобождает  приложение  от  необходимости  определения  типа  и  характеристик  физического  устройства,  что  было необходимо  при  разработке  программ  для MS DOS.  Правильным  образом  написанное  приложение  Windows  будет  при  наличии  соответствующего  драйвера  корректно  работать  с  любым  оборудованием,  как  существующим  на  момент  разработки  приложения,  так  и  с  тем,  которое  появится   в   будущем.  

При  написании  картины  художник  использует  лист  бумаги  или  холст,  на  который  при  помощи  кистей,  красок  и  других  инструментов  наносит  изображение.  Аналогичным  образом  действуют  и  приложения  Windows.  Приложение  использует  устройство  отображения    в  качестве  “холста”,  на  который  при  помощи  инструментов  для  рисования  наносится  изображение. Устройство  отображения   описывается   структурой  данных  типа  HDC,  которая  называется   контекстом  отображения.  В  этой   структуре  хранятся   различные  характеристики  устройства  отображения  (контекст  устройства) и  набор  инструментов  для  рисования,  выбранных  в  контекст  по  умолчанию.  Инструменты  для  рисования  -  это  перья,  кисти,  цветовые  палитры,  шрифты,  битовые  изображения  и  т. п.   Перед  формированием  изображения  приложение  выбирает  в  контекст  отображения  нужный  ему  инструмент  при  помощи  соответствующих  функций  GDI.  Функции  рисования  не  имеют  параметров, указывающих,  например,  цвет  или  ширину  линии  -  вся   необходимая   информация   извлекается   из  контекста  отображения.  

4

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

1. Цвет  фона (background color)-  определяет  цвет  фона  окна,  в  котором  формируется  изображение. По  умолчанию  в  контекст  отображения  выбран  белый  цвет  фона.

2. Режим  фона (background mode) -  возможны  два  режима: выбранный по умолчанию непрозрачный режим (OPAQUE), при  котором  в  процессе  вывода  цвет  фона  удаляется (т. е.,  например,  при выводе    текста,  он  будет  находиться  в  белом  прямоугольнике  высотой,  равной  высоте  букв,  независимо  от  цвета  фона)  и  прозрачный режим (TRANSPARENT),  который  при  формировании  изображения  не  меняет  цвет  фона.

3. Режим  рисования (drawing  mode) -  приложение  может  выбирать  один  из  нескольких  режимов  рисования (цвет  изображения  соответствует  выбранной  кисти (режим по умолчанию);  рисование  инвертированием  цвета  фона ;  рисование  черным  или  белым  цветом;  рисование  с  использованием  операции  “ИСКЛЮЧАЮЩЕЕ  ИЛИ” и  ряд  других).

4. Цвет  текста (text color) -  определяет  цвет,  которым  на  экране  отображается  текст.  По  умолчанию  в  контексте  отображения  для  вывода  текста  выбран  черный  цвет.

5.  Шрифт  (font) -  содержит  информацию  о  параметрах  шрифта,  используемого  для  вывода  текста.  По  умолчанию  используется  системный  шрифт  с  переменной  шириной  букв  в  кодировке ANSI.  Системный  шрифт  всегда  автоматически  регистрируется  в  системе.  Для  того,  чтобы  приложение  могло  использовать  другие  шрифты,  они  должны  быть  зарегистрированы  в  системе  при  помощи  приложения   “Control  Panel” (“Панель  управления”).

6. Расстояние  между  буквами (intercharacter spacing) -  определяет  используемое  расстояние  между  буквами  при  выводе  текста.  По  умолчанию  этот  параметр  равен  нулю.

7. Цветовая  палитра (color palette) - набор  цветов, которые  могут  одновременно  отображаться  на  экране.  Цветовые  палитры  используются  только  при  работе  видеоадаптера  в  режиме,  использующем  палитры  (например,  режим  VGA  640х480 , 16  цветов  или  256-цветные  режимы  SVGA). Современные  адаптеры,  работающие  в  режимах  True  Color  не  используют  механизм  палитр.  Приложения  Windows  могут  составить  для  себя  палитру  максимально  из  236  цветов ( 20  цветов  всегда  зарезервированы  для  использования  системой).  Если видеоадаптер  работает  в  режиме,  использующем  палитры,  по  умолчанию  в  контекст  отображения  выбирается  системная  палитра .

 

5

8. Кисть (brush) - используется  для  закрашивания  внутренней  области  окна  приложения  или  замкнутой  геометрической  фигуры.  По умолчанию  в  контекст  отображения  выбрана  кисть  белого  цвета.

9. Начальные  координаты  кисти (brush origin) -  используются  для  определения  координат  точки,  которая  будет  служить  начальной  при  закраске  внутренней  области  фигуры  или  окна.  В  системе  координат,  выбранной  в  контекст  отображения  по умолчанию,  это  точка ( 0 ,  0 ).

10. Режим  закрашивания  многоугольников (polygon-filling mode) -  существует  два  режима  закрашивания  сложных  самопересекающихся  многоугольников: выбранный по умолчанию альтернативный (ALTERNATE),  в  котором  закрашиваются  только области  между  нечетными  и  четными  сторонами  многоугольника,  и  режим заполнения (WINDING),  в  котором  область  самопересечения  закрашивается.

11. Перо (pen) -  используется  для  определения  цвета,  ширины  и  стиля  линий.  По  умолчанию  в  контекст  отображения  выбрано  черное  перо  шириной  в  один  пиксел.

12.  Текущая   позиция   пера (current  pen position) -  используется  для  определения  начальной  точки при рисовании  линии.  По  умолчанию  текущая  позиция  пера  находится  в  точке ( 0 , 0 ).

13. Изображение  bitmap - может быть выбрано в  контекст  отображения  для  дальнейшего отображения  его  в  окне.  По умолчанию  изображение bitmap в контекст  отображения  не  выбирается.

14. Режим  растяжения (stretching  mode) -  влияет  на  способ ,  с  помощью  которого  производится  масштабирование  изображения  bitmap.  По  умолчанию  используется  режим BLACKONWHITE,  при  котором  два  или  большее  количество  соседних  пикселов  преобразуются  в  один  при  помощи  логической  операции  ИЛИ.   В  режиме  WHITEONBLACK  используется  логическая  операция  И.  В  режиме COLORONCOLOR в  процессе  растяжения  изображения  могут  быть  полностью  удалены  отдельные  строки  или  столбцы  символов.  

15. Область  ограничения  (clipping region) -  задает  область  ограничения  вывода .  По умолчанию в контекст  отображения  выбрана  область ограничения ,  совпадающая  со  всей  возможной  областью  вывода ( например ,  если  контекст  отображения  получен для  окна ,  то  область  ограничения  совпадает  с  внутренней  областью  окна).  Приложение  может  выбирать  в  контекст  отображения  область  ограничения практически  произвольной  формы,  исключая  или  включая  в  нее  области  в  виде  прямоугольников  и  эллипсов,  что  позволяет  получать  при  отображении  интересные  эффекты.

16. Режим  отображения  (map mode) -  определяет  направление  и  масштаб  координатных  осей.  По  умолчанию  выбран  режим  MM_TEXT,  для  которого  начало  координат  находится  в  левом  верхнем  углу  области  отображения,  ось  Х  направлена  вправо,  а  ось  Y  -  вниз.  В  качестве  единицы  измерения   используется  один  пиксел.

6

17. Начало  системы  координат  для  окна (window  origin) -  определяет  начало  системы координат  для  окна ,  по  умолчанию  используется  точка  (0,0).

18. Начало  системы  физических  координат  (viewport origin) -  определяет  начало  координат  для  физического  устройства  отображения  ,  по  умолчанию  используется  точка  (0,0).

19. Масштаб  осей  для  окна (window extent) -  определяет  масштаб  осей  для  системы  координат,  связанной  с  окном.  По  умолчанию  используется  масштаб  1 : 1.

20. Масштаб  осей  физических координат  (viewport extent)  -  определяет  масштаб  осей  для  системы  координат,  связанной  с  физическим  устройством  отображения.  По  умолчанию  используется  масштаб  1 : 1.

 Как  правило,  приложения  выполняют  всю  работу  по  формированию изображения  во  время  обработки  сообщения  WM_PAINT,  хотя  иногда  требуется рисовать  и  во  время  обработки  других  сообщений.  В  любом  случае  приложение  должно  придерживаться   следующей  последовательности  действий :

1) получить (или  создать)  контекст  отображения;

2) установить  необходимые  атрибуты  в  контексте  отображения;

3) выполнить  операции  рисования;

4) освободить (или  удалить) контекст  отображения.

Контекст  отображения  является  критическим  ресурсом,  поэтому  его  необходимо  освобождать (удалять)  сразу , как  только  в  нем  отпадет  необходимость. Можно  выделить  несколько  типов  контекста  отображения.

1. Общий  контекст  отображения (common  display context).  Это  наиболее  часто  используемый  контекст отображения.  Приложения  обычно  используют  этот  контекст  для  формирования  изображения  во  внутренней  области  окна (client  region). Для  получения  общего  контекста  отображения  используются  функции  BeginPaint  или  GetDC,  а  для  освобождения  соответственно функции  EndPaint  или ReleaseDC. Функции BeginPaint и EndPaint используются при обработке сообщения WM_PAINT, а функции GetDC и ReleaseDC – во всех остальных случаях.

2.  Контекст  отображения  для  класса  окна (class  display  context).  Этот  контекст  создается  Windows  при  регистрации  класса  окна со  стилем  класса  CS_CLASSDC ,  хранится  отдельно  от  других  контекстов  в  единственном  экземпляре  и  используется  для  всех  окон ,  созданных  на  базе  данного  класса.  Однажды  получив  такой  контекст,  приложение  может  не  освобождать  его  (хотя  освобождение такого контекста  не приводит  к  ошибке -  функции  освобождения  контекста  просто возвращают  управление).  Однако   приложение  должно  получать данный  контекст каждый  раз при  очередном  вызове  обработчика  сообщения ,  выполняющего  рисование.  Это  связано  с  необходимостью  перенастройки  атрибутов  области  ограничения  и  начала системы  физических  координат.    В  отличие  от  общего  контекста  отображения ,  для  рассматриваемого  контекста  можно  настроить  его  атрибуты  только один раз ,  при  первом  получении  контекста.  Затем  ,  всякий  

7

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

3. Личный  контекст  отображения (private  display  context). Этот  контекст  создается  Windows  при  регистрации  класса  окна со  стилем  класса  CS_OWNDC.  Этот  контекст  аналогичен  предыдущему ,  но  экземпляр  контекста  будет  создаваться  Windows  для  каждого  окна ,  созданного  на  базе  данного  класса.   Это  позволяет  приложению  получать  контекст  и  настраивать  его  атрибуты  для  каждого окна только  один  раз  ,  а  не  перед  каждым  вызовом  обработчика  сообщения  ,  выполняющего  рисование ,  как  в  случае  с  общим  контекстом  отображения.  Приложение  может  не  освобождать  полученный  им  личный  контекст  отображения ,  хотя  его  освобождение  не приведет  к  ошибке. Для работы  с  этим  контекстом  используются  те  же  функции ,  что и для работы  с  общим  контекстом  отображения.

         4.  Родительский  контекст  отображения  (parent  display  context).   Этот   контекст  используется   для  дочерних  окон  и  позволяет  дочерним  окнам  унаследовать атрибуты контекста  отображения у  родительского  окна ,  что  во  многих  случаях  упрощает  процедуру  настройки  этих  атрибутов.  Для  использования  родительского  контекста отображения  в  классе ,  на  базе  которого  создается  дочернее  окно , необходимо  указать стиль класса  CS_PARENTDC. Для работы  с  этим  контекстом  используются  те  же  функции,  что и для работы  с  общим  контекстом  отображения.

5.  Контекст  отображения  для  окна (window  display  context).  Особенностью  данного  контекста  является  то,  что  в  нем  выбрана  система  координат,  начало  которой  находится в  левом  верхнем  углу  окна (а не его внутренней области),  что позволяет рисовать в любом месте  окна (в  т. ч.  в  области  заголовка ,  системного  меню  и  т. п.).  Приложение  может  получить  этот  контекст  с  помощью  функции  GetWindowDC и  обязано  освободить  его  при  помощи  функции  ReleaseDC.

6.  Контекст  физического  устройства ( device  context ).  Этот  контекст  используется  для  формирования  изображения  на  некотором  устройстве  вывода.  Наиболее  часто данный  контекст  используется  при  работе  с  принтером ,  хотя  можно  получить  данный  контекст и  для  дисплея ,  если  имеется  необходимость формировать  изображение  в  произвольной  точке  экрана.  В  отличие  от  раннее  рассмотренных  контекстов  ,  контекст  физического  устройства  не  получается ,  а  создается  приложением  при  помощи  функции  CreateDC.  Созданный  при  помощи  CreateDC контекст  требует  удаления  при  помощи  функции DeleteDC.

7.  Информационный  контекст ( information  context ). Этот  контекст  не  используется  для  формирования  изображения ,  а  создается  обычно  в  тех  случаях ,  когда  приложению  необходимо  просто  получить  информацию  об  устройстве  вывода, например  при помощи функции GetDeviceCaps. Информационный  контекст  создается  при  помощи  функции  CreateIC  и  удаляется  при помощи  функции  DeleteDC

8

8.  Контекст  для  памяти ( memory  device  context ).  При  работе  с  графическими  изображениями  часто  имеет  смысл  предварительно  подготовить  изображение  в  оперативной  памяти ,  а  затем  осуществить  его  вывод  на  некоторое  устройство  вывода.  В  таких  случаях  оперативная  память  рассматривается  как  некоторое  устройство  вывода ,  для  которого и  используется  рассматриваемый  контекст.  Контекст  для  памяти  создается  при  помощи  функции  CreateCompatibleDC  и  удаляется  при  помощи  функции  DeleteDC.

9.  Контекст  для  метафайла (metafile  contexts).  Этот  контекст  позволяет  записывать  команды (вызовы  функций)  GDI  в  файл  ,  находящийся  в  оперативной  памяти  или  на диске.  Затем  можно  “проиграть” этот  файл  на  устройстве  вывода  с  помощью  функции  PlayEnhMetaFile.  Для  создания  контекста  метафайла  используется  функция  CreateEnhMetaFile ,  а  для  удаления  этого  контекста -  функция  CloseEnhMetaFile.  Для  удаления  самого  метафайла  из памяти  используется  функция  DeleteEnhMetaFile , а  для  записи  метафайла  на  диск  -  функция  CopyEnhMetaFile

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

Режим  отображения  -  это  атрибут ,  влияющий  на  используемую  функциями  GDI  систему  координат.  При  отображении  GDI  преобразует  логические  координаты ,  используемые  функциями  GDI,  в  физические  координаты,  непосредственно  связанные  с  физическим  устройством  вывода.  Способ  преобразования  зависит  от  режима отображения. Для  установки  режима отображения,  непосредственно определяющего направление  осей  и  размер  логической  единицы  системы  координат,  используется  функция  SetMapMode. Параметр этой функции  определяет  один  из  восьми  возможных  режимов  отображения :  MM_TEXT  ,  MM_LOMETRIC  ,  MM_HIMETRIC  ,  MM_LOENGLISH , MM_HIENGLISH  ,  MM_TWIPS  ,  MM_ISOTROPIC  ,  MM_ANISOTROPIC . С  помощью  функции  GetMapMode  приложение  может  определить  текущий  режим  отображения.  Для  изменения  ориентации  и  масштаба  осей  в  режимах  MM_ISOTROPIC  и  MM_ANISOTROPIC  используются  функции  SetViewportExt , SetViewportExtEx , SetWindowExt  и SetWindowExtEx. Для  определения  параметров  физического  устройства   вывода   используется   функция  GetDeviceCaps.

Кроме установки режима отображения, приложение обычно выбирает в контекст отображения инструменты для рисования. К ним относятся следующие объекты GDI: перья (pens), кисти (brushes), шрифты (fonts), битовые образы (bitmaps) и прямоугольные области (regions). Приложение может пользоваться встроенными в Windows инструментами для рисования, или создавать собственные при помощи соответствующих функций API. Для использования встроенного объекта GDI следует  получить  идентификатор  объекта при помощи

9

функции GetStockObject. Выбор инструмента для рисования в контекст отображения выполняется с помощью функции SelectObject. После окончания работы с инструментом для рисования, его следует удалить при помощи функции DeleteObject. При этом необходимо предварительно выбрать в контекст отображения один из встроенных инструментов.

 Для  рисования  линий  приложение может  выбрать в контекст отображения одно из  трех  встроенных  перьев  или  создать  собственное  перо. Имеется три встроенных пера: BLACK_PEN,  WHITE_PEN,  NULL_PEN. Для  создания  собственного  пера  приложение  может  воспользоваться  функциями CreatePen или CreatePenIndirect.  Эти  функции  позволяют  создать  перо,  рисующее  сплошные ,  штриховые , штрихпунктирные и  другие  типы  линий  заданной  толщины  и  цвета.  Функции возвращают  идентификатор  пера  типа  HPEN ,  который  потом  необходимо  использовать  в  качестве  параметра  функции SelectObject.

Для  установки  режима  фона  предназначена  функция  SetBkMode,  а  для  определения  текущего  режима  фона -  функция  GetBkMode.  С  помощью  функций  SetBkColor  и GetBkColor  можно  соответственно установить  и  определить текущий  цвет  фона,  который  используется  для  закрашивания  промежутков  между  штрихами  и  точками  линий. Для  выбора  режима  для  рисования  используется  функция  SetROP2  ,  а для  определения  текущего  режима  -  функция  GetROP2.  Для  установки  текущей  позиции  пера  используется  функция MoveToEx,  а  для  определения  текущей  позиции  пера  -  функция  GetCurrentPositionEx.

Для  закрашивания  внутренней  области  замкнутых  фигур  приложение  может  использовать  либо  встроенные  кисти ,  либо  кисти  ,  созданные  самим  приложением. Имеются следующие встроенные кисти: BLACK_BRUSH, WHITE_BRUSH,       GRAY_BRUSH,    LTGRAY_BRUSH, DKGRAY_BRUSH, NULL_BRUSH , HOLLOW_BRUSH. Для  создания  собственной  кисти  приложение  может  воспользоваться  функциями  CreateSolidBrush,  CreateHatchBrush ,  CreatePatternBrush.  Эти  функции  возвращают идентификатор  кисти  типа  HBRUSH , который  потом  необходимо  использовать  в  качестве  параметра функции SelectObject.

Для  вывода  текстовой  информации  приложение может воспользоваться  одним  из  встроенных  в Windows  шрифтов: SYSTEM_FONT, SYSTEM_FIXED_FONT,            ANSI_VAR_FONT,   ANSI_FIXED_FONT, OEM_FIXED_FONT, DEVICE_DEFAULT_FONT, DEFAULT_GUI_FONT. После  получения  идентификатора шрифта ,  этот шрифт  следует  выбрать в  контекст    отображения    при    помощи   функции    SelectObject. Для полного использования  шрифтовых  возможностей  Windows  приложение должно  создать  логический  шрифт  при  помощи  функций CreateFont или CreateFontIndirect.  Эти функции  возвращают  идентификатор шрифта  типа  HFONT.  При  этом  выбирается  шрифт максимально подходящий  по параметрам  запрошенному  и  зарегистрированный  в  системе.  Затем  следует выбрать данный   шрифт   в   контекст   отображения   с   помощью  функции  SelectObject.

10

Приложение может также запросить используемый шрифт у пользователя. Для этого с помощью функции ChooseFont на экран выдается стандартная диалоговая панель выбора шрифта. Параметром этой функции является структура типа CHOOSEFONT, одно из полей которой является указателем на структуру LOGFONT, заполняемую функцией ChooseFont характеристиками логического шрифта в соответствии с выбором пользователя. Структура LOGFONT должна затем использоваться как параметр функции CreateFontIndirect для создания логического шрифта. Приложение также имеет возможность не доверять описанную выше операцию пользователю, а непосредственно просмотреть список зарегистрированных в системе шрифтов. Для этого используется функция EnumFontFamilies. Эта функция последовательно просматривает список зарегистрированных шрифтов указанного семейства (FF_DECORATIVE, FF_ROMAN, FF_DONTCARE, FF_MODERN, FF_SCRIPT, FF_SWISS) и при обнаружении очередного шрифта вызывает определенную в приложении и заданную в качестве одного из параметров функции EnumFontFamilies косвенно-вызываемую функцию EnumFontFamProc. Эта функция получает полную информацию о шрифте, включая указатель на структуру ENUMLOGFONT, полями которой являются структура LOGFONT и строки с названием и типом шрифта. Таким образом, функция EnumFontFamProc получает возможность по названию зарегистрированного шрифта определить его логические характеристики, после чего полученную структуру LOGFONT можно использовать как параметр функции CreateFontIndirect для создания логического шрифта.

В Windows используются два типа битовых образов bitmap: аппаратно-независимый формат DIB и аппаратно-зависимый формат DDB. Формат DIB используется обычно для хранения битовых образов в файлах и передачи их между процессами через Clipboard. Именно в формате DIB сохраняют битовые образы графические редакторы, например редактор Paint, входящий в комплект поставки Windows 95 и Windows NT 4.0. Приложение имеет возможность непосредственно считать содержимое файла в формате DIB в оперативную память. При этом в выделенный блок памяти следует поместить все содержимое файла, за исключением заголовка, определенного структурой BITMAPFILEHEADER. Содержимое полученного таким образом блока памяти называют упакованным форматом хранения DIB. Затем приложение может отобразить битовый образ в заданном контексте отображения. Для отображения битового образа в формате DIB служат функции StretchDIBits и SetDIBitsToDevice. Этим функциям требуется указатель на структуру BITMAPINFO, с которой начинается блок памяти, хранящий упакованный формат DIB. Упакованный формат DIB может быть использован также для создания кисти при помощи функции CreateDIBPatternBrush. Приложение может сформировать в памяти битовый образ в формате DIB при помощи функции CreateDIBSection.

Однако, битовый образ в формате DIB не является объектом GDI. Если приложению необходимо динамически изменять битовый образ с использованием

11

средств GDI, оно должно преобразовать полученный из файла упакованный формат DIB в битовый образ формата DDB, который является объектом GDI. Для этого служит функция CreateDIBitmap. Кроме того, для создания битового образа в формате DDB можно воспользоваться функциями CreateBitmap, CreateBitmapIndirect, CreateCompatibleBitmap или  загрузить  его  из  ресурсов  приложения  при помощи функции LoadBitmap. Вновь созданный или загруженный битовый образ может быть заполнен символьным массивом, содержащим биты битового образа при помощи функции SetBitmapBits. Обратную операцию выполняет функция GetBitmapBits. Затем следует создать контекст отображения для памяти с помощью функции CreateCompatibleDC и выбрать битовый образ в формате DDB в этот контекст при помощи функции SelectObject. Особо следует отметить, что битовый образ может быть выбран только в контекст отображения для памяти. После выполнения этой операции поверхность отображения в выбранном контексте будет иметь те же ширину, высоту и организацию цвета, что и соответствующий битовый образ. Теперь приложение имеет возможность модифицировать битовый образ при помощи функций GDI. К сожалению, в GDI отсутствует функция, позволяющая непосредственно отобразить битовый образ в другом контексте отображения. Вместо этого используется функция BitBlt, осуществляющая перенос битов из одного контекста отображения в другой. Именно при помощи этой функции можно отобразить битовый образ в контексте отображения, связанном с устройством вывода.

Последним из рассматриваемых объектов GDI является регион – описание области вывода, состоящей из комбинации многоугольников и эллипсов. Регионы используются обычно для закрашивания некоторых областей произвольной формы, а также для ограничения вывода (отсечения). Регион создается одной из следующих функций: CreateRectRegion, CreateRectRegionIndirect, CreateEllipticRegion, CreateEllipticRegionIndirect, CreateRoundRectRegion, CombineRegion. Созданный регион может быть выбран в контекст физического устройства при помощи функций SelectObject или SelectClipRgn. Затем следует вызвать функцию InvalidateRgn с тем, чтобы окно получило сообщение WM_PAINT и перерисовало свое содержимое. При этом изображение, находящееся вне выбранного в контекст физического устройства региона не будет перерисовываться.

Многие  функции  GDI требуют  в  качестве  одного из  своих  параметров  ссылку  на  используемый  цвет.  Цвет  указывается  при  помощи  переменной,  имеющей  тип  COLORREF. Значение переменной этого типа представляет собой целое 32-разрядное число, три младших байта которого задают интенсивность красного, зеленого и синего цвета, а старший байт всегда равен нулю. В простейшем  случае  цвет  можно определить с  помощью  макрокоманды  RGB, комбинирующей  цвет  из  отдельных  компонент. Кроме того, определены также макрокоманды,  извлекающие из переменной  типа COLORREF отдельные  цветовые компоненты GetRValue, GetGValue, GetBValue. В  зависимости  от  используемого        видеорежима         Windows          предоставит        приложению  

12

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

Интерфейс  GDI  предоставляет  достаточно  широкий  набор  функций, предназначенных  непосредственно для  формирования  изображения  и  отображения  текстовой  информации  на  устройстве  вывода. Использование этих функций предлагается для самостоятельного изучения.

 

 Пример выполнения работы

 Рассмотрим  приложение  LAB4, демонстрирующее основные приемы программирования приложений Windows с использованием интерфейса GDI.

Это приложение отображает в рабочей области своего окна различные объекты GDI с использованием различных атрибутов. С помощью пункта меню "Рисование" выбирается вид отображаемого объекта. Пункт меню "Фон окна" позволяет изменять режим фона, а пункт меню "Растровая операция" служит для изменения режима рисования. С помощью пункта меню "Шрифты" можно выбрать семейство шрифтов и ориентацию шрифта. Для демонстрации работы с контекстом отображения для окна в области заголовка окна отображается зеленый прямоугольник.

В листинге 4.1 приведен заголовочный  файл приложения.

 Листинг  4.1   Файл  lab4\source\lab4.h

#define STRICT

#include <windows.h>

#define CM_OPAQUE          302

#define CM_TRANSPARENT     303

#define CM_POLYGON         305

#define CM_ELLIPSE         308

#define CM_RECT            309

#define CM_LINES           311

#define CM_EXIT            320

#define CM_R2_MASKNOTPEN   203

#define CM_R2_NOTCOPYPEN   204

#define CM_R2_MASKPENNOT   205

#define CM_R2_NOT          206

#define CM_R2_XORPEN       207

#define CM_R2_NOTMASKPEN   208

#define CM_R2_MASKPEN      209

#define CM_R2_NOTXORPEN    210

#define CM_R2_NOP          211

#define CM_R2_MERGENOTPEN  212

#define CM_R2_COPYPEN      213

#define CM_FONT30          404

#define CM_FONT45          405

#define CM_FONT90          406

#define CM_FONT180         407

#define CM_FONT270         408

#define CM_FONT360         409

13

#define CM_FONT00          410

#define CM_FDECOR          411

#define CM_FMODERN         412

#define CM_FROMAN          413

#define CM_FSCRIPT         414

#define CM_FSWISS          415

#define CM_BITMAP          425

extern short cxClient, cyClient; // Размеры внутренней области окна

extern HINSTANCE hInstance; //Идентификатоp пpиложения

//Фyнкция обpаботки сообщений по yмолчанию

#define Lab4_DefProc  DefWindowProc

//Фyнкция обpаботки сообщения WM_CREATE

BOOL Lab4_OnCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct);

//Фyнкция обpаботки сообщения WM_DESTROY

void Lab4_OnDestroy(HWND hwnd);

//Фyнкция обpаботки сообщения WM_PAINT

void Lab4_OnPaint(HWND hwnd);

//Фyнкция pегистpации окна

BOOL Register(HINSTANCE hInst);

//Фyнкция создания окна

HWND Create(HINSTANCE hInst, int nCmdShow);

//Фyнкция окна

LRESULT WINAPI WndProc(HWND hwnd, UINT Message,

                                 WPARAM wParam, LPARAM lParam);

//Фyнкция обpаботки сообщения WM_COMMAND

void Lab4_OnCommand(HWND hwnd,int id,HWND hwndCtl, UINT codeNotify);

// Прототипы функций

void DrawLines(HDC);  void DrawRectangles(HDC);

void DrawPolygon(HDC);void DrawEllipse(HDC);

// Рисование линий различной толщины и стиля

void DrawLines(HDC hdc)

{ HPEN hpenW10, hpenW50;

 HPEN hpenDot, hpenDash, hpenDashDot, hpenOldPen;

 // Создаем несколько перьев: два пера толщиной

 // 1 мм и 5 мм, пунктирное, штриховое и штрих-пунктирное

 hpenW10      = CreatePen(PS_SOLID, 10,  RGB(0,0,0));

 hpenW50      = CreatePen(PS_SOLID, 50,  RGB(0,0,0));

 hpenDot      = CreatePen(PS_DOT, 0,     RGB(0,0,0));

 hpenDash     = CreatePen(PS_DASH, 0,    RGB(0,0,0));

 hpenDashDot  = CreatePen(PS_DASHDOT, 0, RGB(0,0,0));

 // Рисуем тонкую линию пером, выбранным в контекст

 // отображения по умолчанию, и подписываем эту линию

 MoveToEx(hdc, 100, 100, NULL); LineTo(hdc, 600, 100);

 TextOut(hdc, 700, 100, "PS_SOLID, 1 pixel", 17);

 // Выбираем перо толщиной 1 мм

 hpenOldPen = SelectPen(hdc, hpenW10);

 // Рисуем линию выбранным пером

 MoveToEx(hdc, 100, 200, NULL); LineTo(hdc, 600, 200);

 TextOut(hdc, 700, 200, "PS_SOLID, 1 mm", 14);

 // Перебираем остальные перья

 SelectPen(hdc, hpenW50); MoveToEx(hdc, 100, 300, NULL);

 LineTo(hdc,600,300); TextOut(hdc, 700, 300, "PS_SOLID, 5 mm", 14);

14

 SelectPen(hdc, hpenDot);MoveToEx(hdc, 100, 400, NULL);

 LineTo(hdc, 600, 400); TextOut(hdc, 700, 400, "PS_DOT", 6);

 SelectPen(hdc, hpenDash); MoveToEx(hdc, 100, 500, NULL);

 LineTo(hdc, 600, 500); TextOut(hdc, 700, 500, "PS_DASH", 7);

 SelectPen(hdc, hpenDashDot); MoveToEx(hdc, 100, 600, NULL);

 LineTo(hdc, 600, 600); TextOut(hdc, 700, 600, "PS_DASHDOT", 10);

 // Выбираем старое перо

 SelectPen(hdc, hpenOldPen);

 // Удаляем созданные перья

 DeletePen(hpenW10);  DeletePen(hpenW50);  DeletePen(hpenDot);

 DeletePen(hpenDash);  DeletePen(hpenDashDot);

}

// Рисование прямоугольников

void DrawRectangles(HDC hdc)

{ HPEN hpenW10, hpenOldPen;

 HBRUSH hbrush, hbrushOldBrush;

 POINT pt[2]; RECT rc = {350, 500, 500, 400};

 // Рисуем прямоугольник,занимающий всю внутреннею область окна.

 // Так как установлен метрический режим отображения,

 // а размеры окна, передаваемые вместе с сообщением

 // WM_SIZE, выражены в пикселах, выполняем

 // преобразование физических координат в логические

 pt[0].x = 0; pt[0].y = cyClient;

 pt[1].x = cxClient;  pt[1].y = 0;

 DPtoLP(hdc, pt, 2);

 // Создаем перо толщиной 1 мм и выбираем его

 hpenW10  = CreatePen(PS_SOLID, 10, RGB(0,0,0));

 hpenOldPen = SelectPen(hdc, hpenW10);

 // Рисуем прямоугольник

 Rectangle(hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);

 // Выбираем серую кисть

 hbrush = GetStockBrush(GRAY_BRUSH);

 hbrushOldBrush = SelectBrush(hdc, hbrush);

 // Рисуем прямоугольник, закрашенный серым цветом

 Rectangle(hdc, 100, 500, 300, 50);

 // Создаем и выбираем кисть для штриховки

 hbrush = CreateHatchBrush(HS_DIAGCROSS,RGB(0,0,0));

 SelectBrush(hdc, hbrush);

 // Рисуем заштрихованный прямоугольник

 Rectangle(hdc, 50, 300, 500, 100);

 // Выбираем старое перо и кисть

 SelectPen(hdc, hpenOldPen); SelectBrush(hdc, hbrushOldBrush);

 // Заштриховываем прямоугольную область кистью

 // hbrush, которая НЕ ВЫБРАНА в контекст отображения

 FillRect(hdc, &rc, hbrush);

 // Рисуем прямоугольник со скругленными углами

 RoundRect(hdc, 550, 200, 800, 100, 50, 50);

 // Удаляем созданные перо и кисть

 DeletePen(hpenW10);

 DeleteBrush(hbrush);

}

15

// Рисование многоугольника

void DrawPolygon(HDC hdc)

{ HBRUSH hbrush, hbrushOldBrush;

 int nOldPolyFillMode;

 // Координаты вершин первого многоугольника

 POINT ptPoints1[] = {{10, 10},{100, 310},{40, 300},{300, 15},

                 {135, 340},{113, 125},{250, 137}, {300, 300}};

 // Координаты вершин второго многоугольника

 POINT ptPoints2[] = {{310, 10},{400, 310},{340, 300},

       {600,15},{435, 340}, {413, 125},{550, 137}, {600, 300}};

 // Выбираем встроенную серую кисть

 hbrush = GetStockBrush(GRAY_BRUSH);

 hbrushOldBrush = SelectBrush(hdc, hbrush);

 // Рисуем первый многоугольник в режиме

 // заполнения ALTERNATE, установленном по умолчанию

 Polygon(hdc, ptPoints1,sizeof ptPoints1 / sizeof ptPoints1[0]);

 // Устанавливаем режим заполнения WINDING

 nOldPolyFillMode = SetPolyFillMode(hdc, WINDING);

 // Рисуем второй многоугольник

 Polygon(hdc, ptPoints2,sizeof ptPoints2 / sizeof ptPoints2[0]);

 // Восстанавливаем старый режим заполнения

 SetPolyFillMode(hdc, nOldPolyFillMode);

 SelectBrush(hdc, hbrushOldBrush);

}

// Рисование эллипса

void DrawEllipse(HDC hdc)

{ POINT pt[2];

 // Эллипс будет вписан во внутреннюю область окна, поэтому

 // определяем координаты углов в текущей (метрической) системе

 // координат,выполняя преобразование

 pt[0].x = 0; pt[0].y = cyClient;

 pt[1].x = cxClient; pt[1].y = 0;

 DPtoLP(hdc, pt, 2);

 // Рисуем эллипс

 Ellipse(hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);

}

 Помимо констант и прототипов функций, заголовочный файл также содержит функции для рисования некоторых фигур.

Функция DrawLines служит для рисования линий различной толщины и стиля. Для рисования каждой линии с помощью функции CreatePen создается отдельное перо. Определенная, как и другие макрокоманды, в файле windowsx.h, макрокоманда SelectPen выбирает созданное перо в контекст отображения, возвращая идентификатор ранее выбранного в контекст отображения пера. Эта макрокоманда использует функцию SelectObject. Непосредственно для рисования используются функции MoveToEx и LineTo, а для отображения текста - функция TextOut. Перед завершением работы функция DrawLines выбирает в контекст отображения старое перо макрокомандой SelectPen и удаляет созданные перья при помощи макрокоманды DeletePen, использующей функцию DeleteObject.

16

Функция DrawRectangles выполняет рисование прямоугольников. Вначале отображается прямоугольник, занимающий всю внутреннею область окна. Для преобразования физических координат внутренней области окна в логические координаты окна используется функция DPtoLP. Затем отображаются прямоугольники, один из которых закрашен серым цветом, другой - заштрихован, а третий представляет собой прямоугольник со скругленными углами. Собственно для рисования обычных прямоугольников используется функция Rectangle, а для рисования прямоугольника со скругленными углами - функция RoundRect. Для рисования контуров обычных прямоугольников используется перо стиля PS_SOLID, создаваемое функцией CreatePen и выбираемое в контекст отображения  макрокомандой SelectPen. Контуры прямоугольника со скругленными углами  отображаются пером, выбранным в контекст отображения по умолчанию. Для заполнения прямоугольника серым цветом макрокомандой GetStockBrush создается встроенная кисть стиля GRAY_BRUSH. Для создания кисти эта макрокоманда пользуется функцией GetStockObject. Кисть для заштриховки прямоугольника создается функцией CreateHatchBrush. Созданные кисти выбираются в контекст отображения макрокомандой SelectBrush. Кроме того, функция DrawRectangles заштриховывает прямоугольную область при помощи функции FillRect. Заметим, что эта функция требует в качестве одного из параметров явного указания идентификатора созданной кисти и игнорирует кисть, выбранную в данный момент в контекст отображения. Созданные перья удаляются макрокомандой DeletePen, а кисти - макрокомандой DeleteBrush.

Функция DrawPolygon осуществляет рисование двух многоугольников. Собственно для рисования многоугольников используется функция Polygon, а для установки режима заполнения - функция SetPolyFillMode.

 Функция DrawEllipse рисует эллипс, вписанный во внутреннюю область окна. Для преобразования координат используется функция DPtoLP, а собственно для рисования - функция Ellipse.

В листинге 4.2 приведен файл описания ресурсов.

  Листинг  4.2   Файл  lab4\source\lab4.rc

#include <windows.h>

#include "lab4.h"

BitMap BITMAP "SKY.BMP"

MENU_1 MENU

BEGIN

 POPUP "&Рисование..."

 BEGIN

   MENUITEM "&Прямые линии",   CM_LINES

   MENUITEM "&Прямоугольники", CM_RECT

   MENUITEM "&Многоугольники", CM_POLYGON

   MENUITEM "&Эллипс",         CM_ELLIPSE

   MENUITEM SEPARATOR

   MENUITEM "&BITMAP", CM_BITMAP

   MENUITEM SEPARATOR

   MENUITEM "&Выход", CM_EXIT

 END

17

 POPUP "&Фон окна"

   BEGIN

     MENUITEM "&Opaque",        CM_OPAQUE

     MENUITEM "&Transparent",   CM_TRANSPARENT

   END

 POPUP "&Растpовая опеpация"

   BEGIN

     MENUITEM "R2_MASKNOTPEN",  CM_R2_MASKNOTPEN

     MENUITEM "R2_NOTCOPYPEN",  CM_R2_NOTCOPYPEN

     MENUITEM "R2_MASKPENNOT",  CM_R2_MASKPENNOT

     MENUITEM "R2_NOT",         CM_R2_NOT

     MENUITEM "R2_XORPEN",      CM_R2_XORPEN

     MENUITEM "R2_NOTMASKPEN",  CM_R2_NOTMASKPEN

     MENUITEM "R2_MASKPEN",     CM_R2_MASKPEN

     MENUITEM "R2_NOTXORPEN",   CM_R2_NOTXORPEN

     MENUITEM "R2_NOP",         CM_R2_NOP

     MENUITEM "R2_MERGENOTPEN", CM_R2_MERGENOTPEN

     MENUITEM "R2_COPYPEN",     CM_R2_COPYPEN

   END

 POPUP "&Шpифты..."

 BEGIN

   POPUP "&Шpифт..."

   BEGIN

     MENUITEM "FF_DECORATIVE",  CM_FDECOR

     MENUITEM "FF_MODERN",      CM_FMODERN

     MENUITEM "FF_ROMAN",       CM_FROMAN

     MENUITEM "FF_SCRIPT",      CM_FSCRIPT

     MENUITEM "FF_SWISS",       CM_FSWISS

   END

   MENUITEM SEPARATOR

   POPUP "&Оpиентация..."

   BEGIN

     MENUITEM "0", CM_FONT00

     MENUITEM "30",CM_FONT30

     MENUITEM "45",CM_FONT45

     MENUITEM "90",CM_FONT90

     MENUITEM "180",CM_FONT180

     MENUITEM "270",CM_FONT270

     MENUITEM "360",CM_FONT360

   END

 END

END

 В листинге 4.3 приведен файл основного модуля приложения.

 Листинг  4.3   Файл  lab4\source\lab4.cpp

#define STRICT

#include <windows.h>

#include <windowsx.h>

#include <win32\wingdi.h>

#include <commdlg.h>

#include "Lab4.h"

char szAppName[]="Лабоpатоpная pабота N 4";

18

HINSTANCE hInstance; //Идентификатоp пpиложения

short cxClient, cyClient; // Размеры внутренней области окна

HWND MainWindow;

int nFigures = 0; // Код выбранной строки меню "Рисование"

int nBitMap=0; // Код выбpанного пyнкта меню BITMAP

int nBkMode = TRANSPARENT; // Режим фона

int nROP2 = R2_COPYPEN;  // Код растровой операции

char szChars[] = ": AaBbCcDdEeFfGg "

char szBuf[256];

int nOrientation = 0; // Угол наклона строки при выводе

static LOGFONT lf; 

static HFONT hfont, hfOldFont;

HBITMAP hBitMap; int AHeight, AWidth;

//Главная фyнкция пpогpаммы

#pragma argsused

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance,

                  LPSTR lpszCmdParam, int nCmdShow)

{  MSG Msg;

  if(!hPrevInstance) if(!Register(hInst))return FALSE;

  MainWindow=Create(hInst, nCmdShow); if(!MainWindow)return FALSE;

  while (GetMessage(&Msg, NULL, 0, 0))

 { TranslateMessage(&Msg); DispatchMessage(&Msg); }

 return Msg.wParam; }

//Регистpация окна

BOOL Register(HINSTANCE hInst)

{ WNDCLASSEX WndClassEx;

 WndClassEx.cbSize=sizeof(WNDCLASSEX);

 WndClassEx.style=CS_HREDRAW | CS_VREDRAW;

 WndClassEx.lpfnWndProc=WndProc;

 WndClassEx.cbClsExtra=0; WndClassEx.cbWndExtra=0;

 WndClassEx.hInstance=hInst;

 WndClassEx.hIcon=LoadIcon(NULL, IDI_APPLICATION);

 WndClassEx.hCursor=LoadCursor(NULL, IDC_ARROW);

 WndClassEx.hbrBackground=(HBRUSH)(LTGRAY_BRUSH);

 WndClassEx.lpszMenuName="MENU_1";

 WndClassEx.lpszClassName=szAppName;

 WndClassEx.hIconSm=LoadIcon(NULL, IDI_APPLICATION);

 return (RegisterClassEx(&WndClassEx)!=0); }

//Создание окна

HWND Create(HINSTANCE hInst, int nCmdShow)

{ hInstance=hInst;

 HWND hwnd=CreateWindow(szAppName, szAppName,WS_OVERLAPPEDWINDOW,

        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,

                        NULL, NULL, hInst, NULL);

 if(hwnd==NULL)return hwnd; nCmdShow=SW_SHOWMAXIMIZED;

 ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd);

 return hwnd; }

//Фyнкция окна, обpабатывающая сообщения

LRESULT WINAPI WndProc(HWND hwnd, UINT Message,

                      WPARAM wParam, LPARAM lParam)

{    switch(Message)

       {

19

    case WM_SIZE:

    cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0;

         HANDLE_MSG(hwnd, WM_CREATE, Lab4_OnCreate);

         HANDLE_MSG(hwnd, WM_COMMAND, Lab4_OnCommand);

         HANDLE_MSG(hwnd, WM_DESTROY, Lab4_OnDestroy);

          HANDLE_MSG(hwnd, WM_PAINT, Lab4_OnPaint);

        default:return Lab4_DefProc(hwnd, Message, wParam, lParam);

       }

}

//Фyнкция обpаботки сообщения WM_CREATE

#pragma argsused

BOOL Lab4_OnCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct)

{ BITMAP BStruct;

 hBitMap=LoadBitmap(lpCreateStruct->hInstance, "BitMap");

 GetObject(hBitMap, sizeof(BITMAP), &BStruct);

 AWidth=BStruct.bmWidth; AHeight=BStruct.bmHeight;

 return TRUE; }

//Фyнкция обpаботки сообщения WM_DESTROY

#pragma argsused

void Lab4_OnDestroy(HWND hwnd)

{ DeleteObject(hBitMap); PostQuitMessage(0); }

//Обpаботчик сообщения WM_PAINT

#pragma argsused

void Lab4_OnPaint(HWND hwnd)

{ PAINTSTRUCT ps; //стpyктypа для pисования

 HDC hdc; //идентификатоp контекста yстpойства

 HBRUSH hbrush, hbrushOldBrush; //идентификатоpы кистей

 POINT p;

 int nCapHeight, nFrameHeight; //pазмеpы pамки окна

 // Рисуем в области заголовка окна

 // Получаем контекст отображения для всего окна

hdc = GetWindowDC(hwnd);

nCapHeight = GetSystemMetrics(SM_CYCAPTION);//высота заголовка окна

 nFrameHeight = GetSystemMetrics(SM_CYFRAME);//толщина рамки окна

hbrush = CreateSolidBrush(RGB(0,0xff,0)); //кисть зеленого цвета

hbrushOldBrush = SelectBrush(hdc, hbrush);

 // Рисуем зеленый прямоугольник в заголовке окна

Rectangle(hdc,14*nCapHeight,nFrameHeight,16*nCapHeight,nCapHeight);

SelectBrush(hdc, hbrushOldBrush); // Выбираем старую кисть

 ReleaseDC(hwnd, hdc); // Освобождаем контекст отображения

 // Рисуем во внутренней области окна

 hdc = BeginPaint(hwnd, &ps); // Получаем контекст отображения

//Если был выбpан пyнкт меню BITMAP, то pисyем pастpовое изобpажение

 if(nBitMap)

 { HDC MemDC=CreateCompatibleDC(hdc);

   SelectBitmap(MemDC, hBitMap);

   BitBlt(hdc, 0, 0, AWidth, AHeight, MemDC, 0, 0, SRCCOPY);

   DeleteObject(MemDC);}

 // Устанавливаем метрическую систему координат с началом

 // координат в левом нижнем углу внутренней области окна

 SetMapMode(hdc, MM_LOMETRIC);

 SetViewportOrgEx(hdc,0,cyClient,&p);

20

 // Устанавливаем режим фона и режим рисования

 SetBkMode(hdc, nBkMode); SetROP2(hdc, nROP2);

 // В зависимости от nFigures вызываем одну из функций рисования

 switch(nFigures)

 { case CM_LINES: DrawLines(hdc); break;

   case CM_RECT:  DrawRectangles(hdc); break;

   case CM_POLYGON:DrawPolygon(hdc); break;

   case CM_ELLIPSE:DrawEllipse(hdc); break;

   default: break; }

lf.lfOrientation=lf.lfEscapement=nOrientation;// угол наклона строки

 // Создаем шрифт на базе заполненной структуры LOGFONT

 hfont = CreateFontIndirect(&lf);

 if(hfont)

 { hfOldFont = SelectFont(hdc, hfont); // Выбираем шрифт в контекст

   GetTextFace(hdc, 80, szBuf); // Определяем название шрифта

    lstrcat(szBuf, szChars); // Добавляем к нему текстовую строку

   SetTextColor(hdc,RGB(0,0,0xff)); // Устанавливаем цвет текста

   SetMapMode(hdc, MM_TEXT); SetViewportOrgEx(hdc, 0, 0, &p);

   TextOut(hdc, cxClient/2, cyClient/2,szBuf, lstrlen(szBuf));

   SelectFont(hdc, hfOldFont); // Выбираем старый шрифт

   DeleteFont(hfont); // Удаляем созданный шрифт }

 EndPaint(hwnd, &ps); //Освобождаем контекст отображения

}

//Фyнкция обpаботки сообщения WM_COMMAND

void Lab4_OnCommand(HWND hwnd,int id, HWND hwndCtl, UINT codeNotify)

{switch(id)

{case CM_EXIT:

 if( IDYES == MessageBox(hwnd, "Завеpшить пpогpаммy?",

                  "Выход", MB_YESNO | MB_ICONQUESTION ) )

 DestroyWindow(hwnd); break;

 case CM_LINES:

 {nFigures = CM_LINES; InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_RECT:

 {nFigures = CM_RECT;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_POLYGON:

 {nFigures = CM_POLYGON;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_ELLIPSE:

 {nFigures = CM_ELLIPSE;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_OPAQUE:

 {nBkMode = OPAQUE;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_TRANSPARENT:

 {nBkMode = TRANSPARENT;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_R2_MASKNOTPEN:

 {nROP2 = R2_MASKNOTPEN;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_R2_NOTCOPYPEN:

 {nROP2 = R2_NOTCOPYPEN;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_R2_MASKPENNOT:

 {nROP2 = R2_MASKPENNOT;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_R2_NOT:

 {nROP2 = R2_NOT;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_R2_XORPEN:

 {nROP2 = R2_XORPEN;InvalidateRect(hwnd, NULL, TRUE);break;}

21

  case CM_R2_NOTMASKPEN:

  {nROP2 = R2_NOTMASKPEN;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_R2_MASKPEN:

  {nROP2 = R2_MASKPEN;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_R2_NOTXORPEN:

 {nROP2 = R2_NOTXORPEN;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_R2_NOP:

  {nROP2 = R2_NOP;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_R2_MERGENOTPEN:

 {nROP2 = R2_MERGENOTPEN;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_R2_COPYPEN:

 {nROP2 = R2_COPYPEN;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_FDECOR:

 {memset(&lf,0,sizeof(LOGFONT));lf.lfPitchAndFamily= FF_DECORATIVE;

  InvalidateRect(hwnd, NULL, TRUE); break; }

 case CM_FMODERN:

 {memset(&lf,0,sizeof(LOGFONT));lf.lfPitchAndFamily = FF_MODERN;

  InvalidateRect(hwnd, NULL, TRUE); break; }

 case CM_FROMAN:

 {memset(&lf, 0, sizeof(LOGFONT)); lf.lfPitchAndFamily = FF_ROMAN;

  InvalidateRect(hwnd, NULL, TRUE); break;}

 case CM_FSCRIPT:

 {memset(&lf, 0, sizeof(LOGFONT)); lf.lfPitchAndFamily = FF_SCRIPT;

  InvalidateRect(hwnd, NULL, TRUE); break; }

 case CM_FSWISS:

 {memset(&lf, 0, sizeof(LOGFONT)); lf.lfPitchAndFamily = FF_SWISS;

  InvalidateRect(hwnd, NULL, TRUE); break; }

 case CM_FONT00:

 {nOrientation = 0;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_FONT30:

 {nOrientation = 300;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_FONT45:

 {nOrientation = 450;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_FONT90:

 {nOrientation = 901;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_FONT180:

 {nOrientation = 1801;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_FONT270:

  {nOrientation = 2701;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_FONT360:

 {nOrientation = 3601;InvalidateRect(hwnd, NULL, TRUE);break;}

 case CM_BITMAP:

 {nBitMap=1;InvalidateRect(hwnd, NULL, TRUE);break;}

 default:break;  }

 FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, DefWindowProc);

}

 Функции WinMain и WndProc приложения Lab4 не имеют никаких особенностей, за исключением того, что сообщение WM_SIZE обрабатывается непосредственно в функции окна WndProc. Обработчик этого сообщения запоминает в глобальных переменных cxClient и cyClient размеры рабочей области окна.

22

Функция Lab4_OnCreate обрабатывает сообщение WM_CREATE. Эта функция загружает из ресурсов приложения графическое изображение bitmap посредством функции LoadBitmap. Затем с помощью функции GetObject определяются характеристики загруженного изображения. После этого его ширина и высота сохраняются в глобальных переменных AWidth и AHeight. 

Обработчик сообщения WM_DESTROY (функция Lab4_OnDestroy) не имеет никаких особенностей, за исключением выгрузки из памяти загруженного графического изображения посредством функции DeleteObject.

Функция Lab4_OnCommand обрабатывает извещения от меню приложения, поступающие с сообщением WM_COMMAND. В зависимости от поступившего извещения функция инициализирует соответствующими значениями глобальные переменные nFigures (тип отображаемой фигуры), nBkMode (режим фона), nRop2 (режим рисования), nOrientation (угол поворота шрифта), nBitMap (флажок рисования графического изображения). В случае выбора типа шрифта функция подготавливает глобальную структуру lf типа LOGFONT и заносит в соответствующее поле константу, соответствующую выбранному семейству шрифтов. После этого во всех случаях вызывается функция  InvalidateRect, которая посылает в очередь сообщений приложения сообщение WM_PAINT с указанием необходимости перерисовки всей рабочей области окна. В случае поступления извещения CM_EXIT на экран с помощью функции MessageBox выдается стандартная диалоговая панель для подтверждения окончания работы программы и при положительном ответе пользователя вызывается функция DestroyWindow, которая уничтожает главное окно приложения, что приводит к завершению работы программы.

Непосредственно рисование в окне приложения выполняется функцией Lab4_OnPaint - обработчиком сообщения WM_PAINT.

Сначала эта функция получает при помощи функции GetWindowDC контекст отображения для окна, при помощи функции GetSystemMetrics определяет высоту заголовка окна и толщину рамки окна, создает кисть зеленого цвета посредством функции CreateSolidBrush, выбирает эту кисть в контекст отображения через макрокоманду SelectBrush, рисует посредством функции Rectangle прямоугольник в заголовке окна, после чего освобождает контекст отображения, вызывая функцию ReleaseDC.

Далее производится рисование в рабочей области окна.

Вначале с помощью функции BeginPaint получается требуемый контекст отображения.

Если установлен флажок рисования графического изображения nBitMap, посредством функции CreateCompatibleDC создается контекст отображения для памяти, макрокомандой SelectBitmap в него выбирается загруженное графическое изображение, при помощи функции BitBlt производится копирование этого изображения в общий контекст отображения, после чего контекст отображения для памяти удаляется функцией DeleteObject.   

Затем устанавливаются режим отображения MM_LOMETRIC и начало координат при помощи функций SetMapMode и SetViewportOrgEx, а также режим

23

фона и режим рисования с помощью функций SetBkMode и SetROP2. При этом используются текущие значения глобальных переменных nBkMode и nROP2.

Далее в зависимости от значения глобальной переменной nFigures вызывается одна из следующих функций: DrawLines, DrawRectangles, DrawPolygon, DrawEllipse.

После этого в соответствующие поля глобальной структуры lf типа LOGFONT заносится текущее значение переменной nOrientation и с помощью функции CreateFontIndirect создается логический шрифт. Этот шрифт выбирается в контекст отображения макрокомандой SelectFont. Затем формируется отображаемая строка, для чего к строке, содержащейся в переменной szBuf, добавляется название шрифта, определяемое при помощи функции GetTextFace. Далее устанавливается цвет текста при помощи функции SetTextColor, изменяется режим отображения и начало координат (функции SetMapMode и SetViewportOrgEx) и текст отображается в окне при помощи функции TextOut.

Перед возвратом из функции Lab4_OnPaint макрокомандой SelectFont в контекст отображения выбирается ранее использовавшийся шрифт, созданный шрифт удаляется макрокомандой DeleteFont и при помощи функции EndPaint освобождается контекст отображения.

 Порядок выполнения работы

  1.  Изучите исходные тексты приложения LAB4 и его работу.
  2.  Получите вариант задания у преподавателя.
  3.  Напишите программу согласно варианту задания.
  4.  Отладьте разработанную программу и покажите результаты работы программы преподавателю.

5.  Составьте отчет по лабораторной работе

Содержание отчета

Отчет по лабораторной работе должен содержать следующие сведения:

  •  название и цель работы;
  •  вариант задания;
  •  листинг разработанной программы с комментариями;
  •  результаты работы программы.

Варианты  заданий

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

24

Задания 9 и 10 предполагают знакомство студента с основами компьютерной графики. Самую необходимую информацию по этому вопросу можно найти в [5].

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

а также использовать "пульверизатор" для постепенного заполнения цветом произвольной области.

2. Аналогично предыдущему заданию, но область для рисования представляет собой весь экран дисплея. Управление приложением осуществляется с помощью контекстного меню.

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

4. Аналогично предыдущему заданию, но область для рисования представляет собой весь экран дисплея. Управление приложением осуществляется с помощью контекстного меню.

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

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

7. По выбору пользователя приложение формирует на экране и распечатывает на принтере отдельные изображения, иллюстрирующие различные возможности интерфейса GDI. Должно быть сформировано не менее пяти различных изображений, демонстрирующих использование перьев, кистей, рисование различных линий и фигур, использование шрифтов и графических изображений bitmap.

 8. Приложение позволяет по пикселам формировать на экране и в памяти цветное изображение некоторого формата в виде отдельных кадров, а затем проигрывать мультфильм.

9. Приложение позволяет пользователю сформировать на экране объемную геометрическую фигуру (куб, шар, конус) в виде прозрачного каркаса, а затем выполнить ее вращение в трех плоскостях.

10. Аналогично предыдущему заданию, но фигуры должны быть не прозрачны и изменять при вращении свой цвет.

25

 Контрольные вопросы

  1.  Расскажите о назначении интерфейса графических устройств GDI.
  2.  Что такое контекст отображения? Расскажите об известных Вам типах контекста отображения.
  3.  Что такое атрибуты контекста отображения? Перечислите основные атрибуты контекста отображения.
  4.  Расскажите об использовании режимов отображения, режимов фона и режимов рисования для формирования изображения.
  5.  Расскажите об использовании перьев и кистей для формирования изображения.
  6.  Расскажите об использовании шрифтов и битовых образов для формирования изображения.

Л и т е р а т у р а

  1.  Деревенсков С.О., Духнич Е.И. Основы программирования для Windows 95 и Windows NT: Учеб. пособие / ВолгГТУ, Волгоград, 1998, - 84 с.
  2.  Рихтер Дж. Windows для профессионалов (программирование в Win32 API для Windows NT 4.0 и Windows 95) / Пер. с англ. – М.: Издательский отдел “Русская редакция” ТОО “Chanel Trading Ltd.”, 1997 – 720 c.:ил.
  3.  Петзолд Ч. Программирование для Windows 95; в 2-х томах / Пер. с англ. – СПб.:BHV-Санкт-Петербург, 1997.
  4.  Фролов А.В., Фролов Г.В. Графический интерфейс GDI в MS Windows – М.: ДИАЛОГ-МИФИ, 1994. – 288 с. – (Библиотека системного программиста; Т. 14)
  5.  Шикин Е.В., Борсеков А.В. Компьютерная графика. Динамика, реалистические изображения.   – М.: ДИАЛОГ-МИФИ, 1995. – 288 с.

Составитель:   Сергей Олегович Деревенсков

 

ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ЭВМ И СИСТЕМ. Методические  указания к лабораторным работам. Часть  III.

   Редактор  Е.И. Кагальницкая

   Темплан 2000 г. , поз. N ____

Подписано в печать _________ . Формат  60 х 84  1/16  Бумага газетная. Печать         офсетная.  Усл. печ. л.  ____ .    Уч. -изд.л.  ___ .  Тираж _____ . Заказ _____ .

   Волгоградский государственный технический университет.

   400066 Волгоград , пр. Ленина , 28.

   РПК "Политехник" Волгоградского государственного технического

   университета.

   400066 Волгоград , ул. Советская , 35.

  


 

А также другие работы, которые могут Вас заинтересовать

39166. Исследование коронного разряда в плотном газе 90.7 KB
  Коронный разряд является самостоятельным разрядом в сравнительно плотном газе. Если к двум электродам между которыми находится газовый промежуток приложить электрическое поле то при определенной разности потенциалов между электродами которую назовем критической и обозначим через...
39168. Фактори, чинники та критерії конкурентоспроможності товару 109.5 KB
  Найчастіше під конкурентоспроможністю товару мають на увазі: властивість сукупність властивостей товару та його сервісу яка характеризується ступенем реального або потенційного задоволення ним конкретної потреби порівняно з аналогічними товарами представленими на цьому ринку; характеристику товару що відображає його відмінність від товаруконкурента за ступенем відповідності конкретній суспільній потребі та за витратами на її задоволення; спроможність товару відповідати вимогам даного ринку у період що аналізується; здатність...
39169. Конституционное право зарубежных стран 4.56 MB
  В учебнике освещаются основные понятия и институты зарубежного конституционного права раскрываются его предмет система источники. Предмет источники и система конституционного права зарубежных стран. Предмет конституционного права зарубежных стран. Источники конституционного права зарубежных стран.
39170. Базова апаратна конфігурація 68.75 KB
  Персональний компютер - універсальна технічна система. Його конфігурацію (склад устаткування) можна гнучко змінювати в міру необхідності. Тим не менш, існує поняття базової конфігурації, яку вважають типовою. У такому комплекті комп'ютер зазвичай поставляється. Поняття базової конфігурації може змінюватися. В даний час в базовій конфігурації розглядають чотири пристрої
39171. Основные положения по нормоконтролю и предварительной защите дипломных работ 729 KB
  Общие требования кафедры к содержанию и структуре дипломной работы 10 4.Общие требования кафедры к оформлению дипломной работы 11 5.Образцы оформления и требования к оформлению отдельных фрагментов дипломной работы: 13 титульный лист образец 1 14 реферат...
39172. ДЕРЖАВНЕ ПРАВО ЗАРУБІЖНИХ КРАЇН 3.29 MB
  Тимченко ДЕРЖАВНЕ ПРАВО ЗАРУБІЖНИХ КРАЇН Рекомендовано Міністерством освіти і науки України як навчальний посібник для студентів КИЇВ2005 вищих навчальних закладів УДК342187075. Б 86 Державне право зарубіжних країн: Навчальний посібник. 504 с ISBN 9663640545 Навчальний посібник являє собою комплекс навчальнометодичних матеріалів до курсу Державне конституційне право зарубіжних країн який є обов'язковим для викладання у вищих юридичних закладах IIIIV рівня акредитації. 2005 Центр навчальної літератури 2005...
39173. Аудит финансовых результатов предприятий торговли ООО «Рассвет» 513.5 KB
  Прибыль – конечный финансовый результат слагается из финансового результата от реализации продукции работ услуг основных средств и иного имущества предприятия и доходов от прочих операций уменьшенных на сумму расходов по этим операциям. Они более полно чем прибыль отражают окончательные результаты хозяйствования потому что их величина показывает соотношение эффекта с наличными или использованными ресурсами. В результатах деятельности предприятия заинтересованы учредители предприятия которые получают дивиденды инвесторы...
39174. ПРАКТИЧЕСКИЙ АСПЕКТ ВЗАИМОДЕЙСТВИЯ СЕМЬИ И ШКОЛЫ 408 KB
  Это прежде всего падение жизненного уровня большинства семей решение проблем экономического а порой и физического выживания усилило социальную тенденцию самоустранения многих родителей от решения вопросов воспитания и личностного развития ребенка. Процесс взаимодействия семьи и школы направлен на активное включение родителей в учебновоспитательный процесс во внеурочную досуговую деятельность сотрудничество с детьми и педагогами. Это семьи где ребёнок живет в постоянных ссорах родителей где родители употребляют спиртные напитки и...