На этом шаге мы рассмотрим некоторые API-функции, применяемые
при работе с графикой.
Класс TCanvas инкапсулирует лишь наиболее популярные приемы работы с чертежными инструментами. В этом разделе перечисляются некоторые функции Windows, которые не инкапсулирует класс TCanvas и которые способны значительно разнообразить текстовый вывод (именно он наиболее обеднен узкими рамками TCanvas).
Перечислим некоторые функции API.
Функция | Описание |
---|---|
function CreateFont (Font: TLogFont): hFont; | Создает новый шрифт на основе данных в параметре Font. Назначение полей структуры TLogFont смотрите после таблицы. |
function DrawText (DC: hDC; pText: PChar; var Rect: TRect; Format: UINT): Integer; | В прямоугольнике Rect выводит многострочный текст, на который указывает pText. Параметр Format используется для форматирования (смотри таблицу 2). |
function ExtTextOut (DC: hDC; X, Y: Integer; Options: Integer; Rect: TRect; pText: PChar; Count: Integer; PX: PInteger): Bool; | Выводит текст с нестандартными межсимвольными расстояниями:
|
function GetBkColor (DC: hDC): TColor; | Возвращает цвет фона. |
function GetBkMode (DC: hDC): Integer; | Возвращает режим прорисовки фона: Opaque - фон прорисовывается заново при выводе текста; Transparent - фон не прорисовывается. |
function GetTextAlign (DC: hDC): Integer; | Возвращает выравнивание текста. |
function GetTextCharacterExtra (DC: hDC): Integer; | Возвращает межсимвольное расстояние. |
function SetBkColor (DC: hDC; Color: TColor): TColor; | Устанавливает новый цвет фона и возвращает старый, если обращение успешно. |
function SetBkMode (DC: hDC; Mode: Integer): Integer; | Устанавливает новый режим прорисовки фона и возвращает старый, если операция успешна. |
function SetTextAlign (DC: hDC; Flags: Integer): Integer; | Устанавливает новое выравнивание текста и возвращает старое, если вызов успешен. |
function SetTextCharacterExtra (DC: hDC; CharExtra: Integer): Integer; | Устанавливает новое межсимвольное расстояние и возвращает старое, если вызов успешен. |
Отдельные поля структуры TLogFont для функции CreateFontIndirect имеют следующий смысл:
Приведем пример использования некоторых рассмотренных конструкций. Пусть, например, нужно создать приложение, при выполнении которого на экране появляется следующее изображение:
Рис.1. Внешний вид приложения
Вот как реализован этот пример:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormPaint(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormPaint(Sender: TObject); var X: Integer; LF: TLogFont; Fnt: HFont; const Text = 'Лучшая в мире система программирования'; begin // Определяем параметры нового шрифта. FillChar(LF, SizeOf(LF), 0); with LF do begin lfHeight := 20; lfWeight := fw_Normal; lfUnderline := 1; lfEscapement := 450; StrPCopy(lfFaceName, 'Courier New Cyr'); end; with Form1.Canvas do begin // Создаем шрифт. Fnt := CreateFontIndirect(LF); // Присваиваем его дескриптор шрифту канвы. Font.Handle := Fnt; // Выводим текст под углом +45 градусов. TextOut(0, 300, Text); X:= TextWidth(Text) ; DeleteObject(Fnt); // Удаляем ненужный шрифт. // Изменяем параметры шрифта. with LF do begin lfHeight := 90; lfEscapement := -900; lfWeight := fw_Heavy; StrPCopy(LF.lfFaceName, 'Arial Cyr'); end; Fnt:=CreateFontIndirect(LF); // Создаем новый шрифт. Font.Handle := Fnt; Font.Color := clRed; // Выводим снаклоном -90 градусов. TextOut(X-10, 10, 'Delphi 6'); DeleteObject(Fnt); // Удаляем ненужный шрифт. end; end; end.
Текст этого примера можно взять здесь.
Параметр Format функции DrawText может содержать один или несколько флагов, перечисленных в таблице 2.
Параметр | Описание |
---|---|
dtBottom | Текст прижимается к нижней части области Rect. |
dtCalcRect | Разрешает динамически изменять размеры области Rect. |
dtCenter | Текст центрируется по горизонтали. |
dtEditControl | Функция дублирует свойства отображения многострочного тестового редактора. В частности, таким же способом вычисляется средняя ширина символа и не показывается частично видимая последняя строка. |
dtExpandTabs | Символы табуляции заменяются пробелами. |
dtExternalLeading | В высоту строки включается высота межстрочного интервала. |
dtLeft | Текст прижимается к левой части области Rect. |
dtNoClip | Текст не отсекается границами Rect. |
dtNoPrefix | Символы & не заменяются подчеркиванием. |
dtRight | Текст прижимается к правой части области Rect. |
dtSingleLine | Весь текст выводится единственной строкой, символы перехода на новую строку игнорируются. |
dtTabsStop | Символы табуляции не заменяются пробелами. |
dtTop | Текст прижимается к верхней части области Rect. |
dtVCenter | Текст центрируется по вертикали. |
dtWordBreak | Разрешает переход на новую строку при достижении правой границы Rect; разрыв строки - на границе слова; символы перевода строки также переводят вывод на следующую строку. |
Если установлен флаг dtCalcRect, функция изменяет высоту и ширину прямоугольника так, чтобы вывести весь текст, но сам текст не выводится. Если в тексте несколько строк, ширина вывода не меняется. Функция возвращает истинную высоту прямоугольника вывода.
Параметр Options функции ExtTextOut может быть комбинацией следующих значений:
При выводе текста стандартными методами TCanvas всегда заново прорисовывается фон символов (цвет фона возвращает функция GetBkColor). Если цвет фона символов отличается от фона канвы, вывод сопровождается неприятными побочными эффектами. Конечно, с помощью функции SetBkColor можно установить цвет формы совпадающим с цветом канвы, однако это не всегда возможно. Ясно, что установить переменный цвет функцией SetBkColor невозможно. Более того, заглавные надписи программ Setup.exe также традиционно выводятся утолщенным наклонным шрифтом Times New Roman белыми буквами с черной тенью. Реализовать такой эффект достаточно просто: нужно вообще отказаться от прорисовки фона, установив с помощью функции SetBkMode режим Transparent, и вывести надпись дважды: первый раз черным цветом, а второй - белым, сместив вторую надпись немного влево и вверх относительно первой:
Рис.2. Внешний вид приложения
Следующий листинг иллюстрирует сказанное:
procedure TForm1.FormPaint(Sender: TObject); var Y: Integer; Blue: Byte; const Text = 'Фон для программы Setup.exe'; begin with Form1.Canvas do begin for Y := 0 to Form1.Height-1 do begin //Уменьшаем интенсивность цвета с ростом ординаты Y. Blue := Round($FF*(Form1.Height-Y)/Form1.Height); Pen.Color := RGB(0, 0, Blue); // Формируем цвет. MoveTo(0, Y); // Чертим линию. LineTo(Form1.Width-1, Y) ; end; Font.Size := 32; Font.Style := [fsBold, fsItalic, fsUnderline]; Font.Name := 'Times New Roman'; // Это обращение накладывает текст на фон. SetBkMode(Handle, Transparent); // Сначала выводим тень надписи. Font.Color := clBlack; TextOut(40, 30, Text); // Теперь саму надпись. Font.Color := clWhite; TextOut(36, 26, Text); end; end;
Текст этого примера можно взять здесь.
На следующем шаге мы рассмотрим такое понятие, как области.