Графические инструменты в Delphi. Дополнительные возможности API-функций

   
На этом шаге мы рассмотрим некоторые API-функции, применяемые
при работе с графикой.

   
Класс TCanvas инкапсулирует лишь наиболее популярные приемы
работы с чертежными инструментами. В этом
разделе перечисляются некоторые функции Windows, которые не
инкапсулирует класс
TCanvas и которые способны значительно разнообразить текстовый
вывод (именно он наиболее
обеднен узкими рамками TCanvas).

   
Перечислим некоторые функции API.

Таблица 1. Некоторые функции
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;
Выводит текст с нестандартными межсимвольными расстояниями:

  • X, Y - верхняя левая точка текста;
  • Options - параметр, управляющий выводом;
  • Rect - ограничивающий прямоугольник;
  • pText - указатель на строку вывода;
  • Count - количество выводимых символов;
  • PX - указатель на массив целочисленных значений,
    определяющих межсимвольные
    расстояния: 1-й параметр - расстояние от 1-го до 2-го символа; 2-й параметр -
    расстояние от 2-го до 3-го символа и т. д. Если какой-то параметр равен 0,
    используется умалчиваемое межсимвольное расстояние.
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 имеют следующий
смысл:

  • lfHeight - высота шрифта в пунктах (1 пункт = 1/72 дюйма). Если
    значение больше
    0, то определяет высоту "знакоместа" (с учетом выступающих над заглавным
    символом элементов в буквах Е, И).
    Если значение меньше нуля - высоту "чистого" символа. Если 0 - высоту
    выбирает Windows;
  • lfWidth - средняя ширина символа; если 0, ширину устанавливает
    Windows;
  • lfEscapment - угол наклона базовой линии текста в десятых долях
    градуса относительно горизонтального
    направления. Положительные значения - поворот по часовой стрелке (в
    Windows 95/98 совпадает c lfOrientation);
  • lfOrientation - угол наклона символов по отношению к базовой линии;
    в Windows NT
    для шрифтов TrueType может отличаться от lfEscapment. Для
    этого следует установить
    режим устройства отображения равным gm_Advanced (по умолчанию
    устанавливается gm_Compatible);
  • lfWeight - плотность шрифта. Возможные значения:
    • fm_DontCare (0) - плотность выбирает Windows;
    • fm_Thin (100) - очень тонкий шрифт;
    • fm_ExtraLight (200) - очень светлый;
    • fm_Light (300) - светлый;
    • fm_Normal (400) - нормальный;
    • fm_Medium (500) - утолщенный;
    • fm_SemiBold (600) - полужирный;
    • fm_Bold (700) - жирный;
    • fm_ExtraBold (800) - усиленный;
    • fm_Heavy(900) - тяжелый;
  • lfItalic, lfUnderline, lfStrikeOut - ненулевые значения задают
    соответственно наклонный, перечеркнутый и подчеркнутый шрифт;
  • lfCharSet - набор символов (ANSI_CharSet (или 0),
    Default_CharSet (1), Symbol_CharSet (2); ShiftJis_CharSet
    (128); OEM_CharSet (255));
  • lfOutPrecision - точность представления шрифта. Рекомендуется
    значение
    OUT_TT_PRECIS (выбирает TrueType и векторные шрифты, если
    есть несколько разновидностей одноименных
    шрифтов) или OUT_TT_ONLY_PRECIS (выбирает только
    TrueType шрифты);
  • lfClipPrecision - определяет точность отсечения надписи границами
    области прорисовки
    (возможные значения: CLIP_CHARACTER_PRECIS, CLIP_EMBEDDED,
    CLIP_MASK, CLIP_TT_ALWAYS, CLIP_DEFAULT_PRECIS
    (рекомендуется), CLIP_LH_ANGLES, CLIP_STROKE_PRECIS);
  • lfQuality - определяет качество прорисовки (DEFAULT_QUALITY,
    DRAFT_QUALITY, PROOF_QUALITY);
  • lfPitchAndFamily - в четырех младших разрядах указывается тип
    шрифта, в четырех старших - его семейство;
  • lfFaceName - имя гарнитуры шрифта.

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


Рис.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.

Таблица 2. Возможные значения
параметра Format функции DrawText

Параметр Описание
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 может быть комбинацией
следующих значений:

  • ETO_СLIPPED - текст будет отсекаться границами Rect;
  • ETO_GLIPH_INDEX - блокирует обработку языковым драйвером;
  • ETO_OPAQUE - фон перерисовывается заново;
  • ETO_RTLREADING - вывод для чтения справа налево.

   
При выводе текста стандартными методами 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;

   
Текст этого примера можно взять здесь.

   
Примечание. Любая заливка фона, в том числе его прорисовка,
реализуется с
помощью кисти. Поэтому отказаться от прорисовки фона текста можно, если
установить стиль
кисти bsClear. Вместо SetBkMode (Handle, Transparent); можно
использовать
Brush.Style:=bsClear;.

   
На следующем шаге мы рассмотрим такое понятие, как области.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий