Опубликован: 17.08.2010 | Доступ: свободный | Студентов: 999 / 59 | Оценка: 4.11 / 3.89 | Длительность: 29:38:00
Самостоятельная работа 8:

Работа MFC с GDI (GDI+)

Управление текстом в GDI

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

Основные функции GDI работы с текстом
  • COLORREF GetTextColor() - возвращает текущий цвет текста.
  • COLORREF SetTextColor(COLORREF) - устанавливает цвет для вывода текста. Возвращает предыдущий цвет текста в виде значения типа COLORREF. Например, красный текст можно установить так
    pDC->SetTextColor(RGB(255, 0, 0));
    pDC->TextOut(x, y, "Это красный текст");
  • int GetBkMode() - возвращает режим отображения фона текста или рисунка ( OPAQUE - непрозрачный, TRANSPARENT - прозрачный). Режим OPAQUE установлен по умолчанию.
  • int SetBkMode(int) - устанавливает режим отображения фона ( OPAQUE - непрозрачный, TRANSPARENT - прозрачный). Возвращает предыдущий режим.
  • COLORREF GetBkColor() - возвращает текущий цвет фона текста. Цвет фона закрашивает само поле текста, а не его символы.
  • COLORREF SetBkColor(COLORREF) - устанавливает цвет фона для вывода текста. Возвращает предыдущий цвет фона текста в виде значения типа COLORREF. Для установленного режима TRANSPARENT цвет фона при прорисовке текста не учитывается.

    Для выбора цвета пользователем ему можно предоставить стандартное диалоговое окно следующим кодом

    Вызов стандартного окна выбора цвета
    CColorDialog colorDlg;
    if(colorDlg.DoModal() == IDOK){
      COLORREF color = colorDlg.GetColor();
      CString strText;
      strText.Format("Вы выбрали цвет RGB( %d, %d, %d )"
          , GetRValue(color)
          , GetGValue(color)
          , GetBValue(color)
              );
      AfxMessageBox(strText);
    }
  • SetTextAlign(int nFlag) - выравнивание текста. Выравнивание текста описывает отношение между указанной координатами (x, y) начальной точкой отображения текста и самим полем, занимаемым текстом. По умолчанию принято выравнивание текста ниже и правее начальной точки вывода текста. Этой функции передается единственный параметр, представляющий собой комбинацию флагов, приведенных в таблице. Флаги, находящиеся в одном столбце, являются взаимоисключающими, т.е. из каждого столбца можно выбрать только один флаг. Флаги, указанные в первой строке, установлены по умолчанию.

    Константы выравнивания текста
    По оси x По оси y Обновить текущую позицию
    TA_LEFT TA_TOP TA_NOUPDATECP
    TA_CENTER TA_BASELINE TA_UPDATECP
    TA_RIGHT TA_BOTTOM

    Например, в приведенном коде текст будет выровнен по правому краю

    pDC->SetTextAlign( TA_RIGHT | TA_TOP );
    pDC->TextOut(x, y, "Это выравненный справа текст");
  • SetTextJustification() - выравнивание текста по ширине. Функция позволяет установить количество пикселов, которые необходимо добавить в каждый символ пробела.
  • SetTextCharacterExtra() - как и предыдущая функция, добавляет пискселы, но не только в пробелы, но и в символы текста.
  • TextOut(int x, int y, CString strText) - размещает текст на поверхности рисунка и принимает три параметра
    • координату x левого верхнего угла поля вывода текста
    • координату y левого верхнего угла поля вывода текста
    • строку с текстом для отображения
  • TabbedTextOut() - отображает текст подобно функции TextOut(), но позволяет задать массив позиций табуляции, чтобы обеспечить представление текста в виде столбцов.
  • ExtTextOut() - более универсальная функция вывода текста, позволяющая контролировать ширину даже отдельных символов. Во-первых, позволяет указать произвольный прямоугольник, ограничивающий область вывода текста. Во-вторых, позволяет отобразить текст в непрозрачном (заполненном цветом фона) прямоугольнике. И в-третьих, позволяет управлять шириной отображаемого тектса (интервалом между символами).
  • GrayString() - создает пятнистый текст, аналогичный используемому в меню, когда соответствующий пункт недоступен.
  • CSize GetTextExtent(CString, int) - вычисляет размер области, которую займет строка текста на рисунке в пикселах при использовании текущего шрифта. Эта функция принимает строку CString, где содержится текст, и возвращает структуру Size, которая имеет два члена: cx - определяющий ширину текста и cy - определяющий высоту текста. Например, приведем код, где текст центрируется относительно курсора.
    Вывод текста относительно центра курсора
    // Отобразить фразу
    // при помощи объекта MFC CClientDC
    void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
    {
      // Создать экземпляр clientDC класса CClientDC
      CClientDC clientDC(this);// контекст для текущего окна
      
      // Создать объект с текстом
      CString strText = "Привет студентам от Снеткова В.М.!";
      
      // Получить размер текстовой строки в пикселах
      CSize size = 
      clientDC.GetTextExtent(strText. strText.GetLength());
      
      // Вычислить такие координаты начала отображения строки, 
      // чтобы центр текста соответствовал курсору мыши
      int xCentered = point.x - (size.cx / 2);
      int yCentered = point.y - (size.cy / 2);
      
      // Отобразить текст в окне
      clientDC.TextOut(xCentered, yCentered, strText);
    }

Рисование в GDI

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

  • CPoint GetCurrentPosition() - возвращает координаты графического курсора GDI.
  • SetPixel(int x, int y, COLORREF RGB(RED, GREEN, BLUE)) - рисует точку текущим пером в заданной позиции графического курсора.
  • MoveTo(int x, int y) - перемещает графический курсор в заданную точку.
  • LineTo(int x, int y) - соединяет текущую позицию графического курсора с заданной точкой линией, цвет и толщина которой определяется параметрами текущего пера. Текущая позиция курсора перемещается в конец линии.
  • Polyline(CPoint point[], int count); PolylineTo(CPoint point[], int count) - обе функции принимают в качестве параметров последовательность точек и рисуют отрезки прямых между ними. Первый параметр - указатель на массив объектов CPoint, второй - количество точек в массиве. Когда функция PolylineTo() завершает работу (возвращает управление клиенту), текущая позиция графического курсора остается в последней точке массива.
  • Polygon(CPoint point[], int count) - рисует замкнутый многоугольник (полигон) по тем же параметрам, что и функции Polyline() и PolylineTo(). Единственное ее отличие - она дорисовывает замыкающее звено, соединяющее последнюю и начальную точки.
  • Rectangle(CRect rect) - рисует прямоугольник по точкам объекта CRect текущим пером и кистью.
  • RoundRect(CRect rect, CPoint ellipse) - рисует прямоугольник со скругленными углами текущим пером и кистью. Второй параметр класса CPoint в значении x содержит ширину, а в значении y - высоту эллипса, который используется для скругления углов.
  • Ellipse(CRect rect); Ellipse(int x1, int y1, int x2, int y2) - перегруженная функция, которая рисует вписанный в прямоугольник эллипс. Прямоугольник задается либо объектом CRect, либо координатами точек левого верхнего и правого нижнего углов. Для прямоугольника с равными сторонами рисуется круг. Эллипс рисуется с помощью текущего пера и кисти.
  • Arc(CRect rect, CPoint ptStart, CPoint ptEnd); Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); ArcTo(CRect rect, CPoint ptStart, CPoint ptEnd); ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); - рисуют дугу между двумя точками. Первая координата rect (или x1,y1 и x2,y2 ) определяет описывающий прямоугольник, остальные - начальную и конечную точки дуги. Дуга рисуется против часовой стрелки от начала к концу. Функция ArcTo() после рисования бросает текущую позицию графического курсора в конечной точке дуги.
  • Pie(CRect rect, CPoint ptStart, CPoint ptEnd); Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); - рисует сегмент эллипса. Она принимает те же параметры, что и функции Arc(), ArcTo(). Дуга на внешнем конце сегмента определяется также, как и в Arc(), ArcTo(). Острие сегмента находится в центре описывающего прямоугольника rect.

Управление растром в GDI

Видеопамять - специфический участок оперативной памяти, содержимое которого немедленно и постоянно отображается на экране. Растр ( bitmap - битовая карта) представляет собой участок оперативной памяти, по структуре являющийся точной копией видеопамяти. Однако в отличие от видеопамяти содержимое растровой памяти ( bitmap memory ) не является отображаемым непосредственно на экране.

Оперативная память, занятая растром, содержит данные, соответствующие прямоугольной области. В терминологии API Windows дескриптор занятой растром области памяти известен как HBITMAP. В этой области памяти можно располагать данные, перемещение которых в видеопамять приведет к отображению на экране изображения или узора.

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

Для управления растром могут использоваться

  1. API -функции, которые обращаются к растрам по дескриптору типа HBITMAP
  2. MFC -класс CBitmap, который является оболочкой для API -функций Windows работы с растром

Создание графического приложения

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

Александр Даниленко
Александр Даниленко
Стоит Windows 8 Pro, Visual Studio 2010 Express Edition .