Вывод текста под углом

В нем надо написать содер­жимое листинга:

 

procedure TFormi. FormMouseDown (Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); 
Var
A: Integer; //Объявление переменной А — целое число, 
begin
А := random(3600);
CanvasSetAngle(Canvas, A / 10) ;
Canvas.TextOut(X, Y, FormatFloat('##0.01, A/10)+'°'); end;

Давайте рассмотрим текст этой процедуры. В первой строке используется функ­ция random, она возвращает случайное значение, но не больше чем число, указан­ное в скобках. В нашем случае это — 3600.

Вторую строку пока опустим, а рассмотрим третью. canvas.Textout— выводит текст на форме, и мы с ней уже работали.

Для вывода текста использовалась функция FormatFloat. Она переводит число с запятой (вещественное или, так сказать, дробное) с учетом формата,

 

function FormatFloat(const Format: string; // Строка формата

Value: Extended // Число ): string;

 

В качестве формата указано ##о.о, что приводит указанное число к этому виду, т. е. отрезает все знаки после запятой, оставляя только один (об этом говорит один ноль после запятой в строке формата). Перед запятой может быть любое количест­во чисел, потому что стоят два знака решетки. В качестве числа указывается пере­менная а, деленная на 10.

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

 

unit Textrotl;

interface

uses

Sysutils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type

TForm1 = class(TForm)

procedure ForrrtMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer); procedure TimerITimer (Sender: TObj ect) ; procedure FormCreate(Sender: TObj ect); private

{ Private-Deklarationen } index:Integer; cl:Boolean; 

public

{ Public-Deklarationen } end;

var

Forml: TFormi ; implementation {$R *.DFM}

procedure CanvasSetAngle(C: TCanvas; A: Single);

var

LogRec: TLOGFONT; // Объявляем переменную логического шрифта

begin

GetObj ect(С.Font.Handle,Si zeOf(LogRec),Addr(LogRec));

LogRec.1fEscapement := Trunc(A*10);

LogRec.lfOrientation := Trunc((A+10) * 100);

С.Font.Handle := CreateFontIndirect(LogRec);

end;

procedure TFormi.FormMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

Var A: Integer;

begin

A := Random(3600); CanvasSetAngle(Canvas, A / 10);

Canvas.TextOut(x, Y, FormatFloat('##0.0'# A/10)+'°');

end;

procedure TFormi.FormCreate(Sender: TObj ect); begin index:=0;

Canvas.Brush.Style:=bsClear;

end;

end.

В качестве параметров для функции canvasSetAngle процедуре передается canvas и угол разворота текста. Угол разворота имеет значение single, что озна­чает вещественное (дробное). Ранее имя процедур вместо нас писал Delphi. Дан­ную процедуру вам придется вписывать своими руками, потому что она самостоя­тельная и не принадлежит никакому объекту. Это очень важно, потому что если она будет принадлежать объекту, то текст не развернется.

 

Теперь перейдем к содержимому процедуры. Рассмотрим по частям первую строку:

  • Getobject — эта функция возвращает информацию о графическом объекте;
  • с.Font.Handle — объект, на который нужно получить значение;
  • sizeof (LogRec) — передаем размер возвращаемого значения;
  • Addr (LogRec) — передаем адрес возвращаемого значения.

С помощью этой функции мы получаем информацию о шрифте, используемом нами для рисования. Вторая и третья строки процедуры изменяют значения полу­ченной информации. Четвертая функция записывает измененную информацию.

 

Запустите получившееся приложение и пощелкайте мышью по форме. В месте щелчка должен появиться текст под случайным углом.

 

Теперь поставьте на форму компонент Timer, который находится на вкладке System. Этот компонент умеет генерировать события через определенные проме­жутки времени. Создайте для таймера обработчик события onTimer и напишите в нем содержимое листинга:

 

procedure TForm1. Timer ITimer (Sender: TObj ect) ; begin

CanvasSetAngle(Canvas, index); Canvas.TextOut(100, 100, 'CyDSoft'); index:=index+45; if index>=360 then begin index:=0; if cl then

Canvas.Font.Color:=clBlack else

Canvas.Font.Color:=clRed; cl:=not cl; end; end;

 

Эта процедура будет вызываться каждый раз, когда пройдет интервал времени, указанный в свойстве interval (интервал) компонента Timer. По умолчанию там указано 1000 (число в миллисекундах, что равно 1 секунде), значит, процедура бу­дет вызываться через каждую секунду. Если свойство Enabled компонента Timer выставлено в true, то таймер генерирует события, иначе он отключен и событие OnTimer срабатывать не будет.

 

Внутри процедуры выставляется угол, на который надо вывести текст (CanvasSetAngle), ПОТОМ ВЫВОДИТСЯ сам текст (С ПОМОЩЬЮ Canvas .TextOut).

После этого прибавляем переменной index значение 45. В этой переменной хранится значение угла, под которым надо вывести текст, и через каждую секунду это значение увеличивается на 45 градусов.

 

Далее идет проверка — если index больше или равен 360, значит, программа просчитала полный круг, а если так, то выполняется следующий код:

 

index:=0; if cl then

Canvas.Font.Color:=clBlack else

Canvas.Font.Color:=clRed;

cl:=not cl;

 

Вывод текста под угломЗдесь в первой строке обнуляется переменная index, чтобы начать вывод текста с 0 градусов (мы же уже прошли полный круг). Дальше проверяется значение пе­ременной cl, если она равна true, то значению цвета текста будет присвоено ciBiack, что эквивалентно черному цвету. Иначе цвет сменится на красный (clRed).

 

После этого изменяется значение переменной cl на противоположное, о чем го­ворит конструкция cl:=not cl. Здесь мы присваиваем переменной противополож­ное (not) значение ее самой. Это значит, что если cl равнялась true, то после этого кода будет равняться false. Таким образом, после прохождения текстом очередно­го круга, цвет будет меняться с черного на красный и обратно.

 

Попробуйте запустить пример. Пускай он немного поработает, чтобы форма за­полнилась текстом. Теперь попробуйте перекрыть окно программы другим окном или свернуть его. Потом снова восстановите окно. Что вы видите? Все, что было нарисовано, — исчезло. Это потому, что Windows не сохраняет содержимое окна. Мы сами должны его восстанавливать.

 

Когда окно свернулось и восстановилось, то генерируется событие onPaint, по которому нужно перерисовать содержимое окна. Поэтому все функции рисования стараются располагать именно в обработчике этого события. Так мы будем рисо­вать и реагировать на события, когда надо перерисовать содержимое экрана одной и той же функцией.

В нашем примере использование события OnPaint неудобно, потому что экран меняется динамически и мы не можем постоянно запоминать его содержимое. В таких случаях на форму ставят компонент Timage и рисуют в нем. Этот компо­нент, в отличие от формы, сохраняет свое содержимое. Когда вы рисуете на холсте компонента Timage, то делаете это в специально отведенной под компонент памя­ти. А вот когда Timage нуждается в прорисовке, эта область памяти копируется на экран. Таким образом, не надо самостоятельно ни за чем следить. Подробнее с компонентом Timage мы познакомимся немного позже.

ЗАМЕЧАНИЕ. Таким образом развернуть можно только TrueType-текст. В последних версиях Delphi в качестве шрифта по умолчанию для холста используется именно такой шрифт. В старых версиях может понадобиться явное указание шрифта в свой­стве Canvas.Font. Если вы сами захотите изменить шрифт, то меняйте его только на TrueType.

 

 
dle

Помоги проекту! Расскажи друзьям об этом сайте: