В нем надо написать содержимое листинга:
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 мы познакомимся немного позже.