2. Свойства и методы формы
Основные свойства формы
Свойство
|
Описание
|
ActiveControl
|
Содержит имя одного из объектов на форме, который в настоящий момент имеет фокус. Имя элемента на этапе проектирования выбирается из выпадающего списка. Этот элемент получит фокус при первом отображении формы.
|
Align
|
Задает выравнивание формы на экране монитора. Значениями являются:
· alNone (значение по умолчанию) — выравнивание формы производиться не будет,
· alBottom — форма выравнивается по нижней части экрана,
· alClient — форма выравнивается по всей поверхности экрана,
· alCustom — у формы будут все элементы управления, заданные другими свойствами формы, размер формы нельзя изменять во время выполнения,
· alLeft — форма выравнивается по левой части экрана,
· alRight — форма выравнивается по правой части экрана,
· alTop — форма выравнивается по верхней части экрана.
|
AlphaBlend
|
Определяет, может ли окно быть прозрачным (true) или нет (false). Свойство AlphaBlendValue задает степень прозрачности окна.
|
AlphaBlendValue
|
Определяет степень прозрачности окна: 0 — окно совершенно прозрачно, 255 — непрозрачно. Свойство AlphaBlend должно быть установлено в значение true.
|
AutoScroll
|
Определяет, будут ли в окне автоматически появляться полосы прокрутки, если при изменении пользователем размеров окна будут скрыты визуальные элементы (true) или нет (false). При этом свойство AutoSize должно быть установлено в значение false.
|
AutoSize
|
Указывает, может ли пользователь изменять размеры окна таким образом, чтобы скрывались визуальные элементы, расположенные на окне (значение по умолчанию false), или возможно только такое изменение размеров, при котором остаются видимыми все элементы (значение true).
|
BorderIcon
|
Определяет наличие кнопок в заголовке формы. Подсвойствами, принимающими значение true или false, являются:
· biSystemMenu — наличие системного меню,
· biMinimize — наличие кнопки минимизации,
· biMaximize — наличие кнопки максимизации,
· biHelp — наличие кнопки помощи.
|
BorderStyle
|
Указывает вид и поведение ограничивающей рамки у формы. Значениями являются:
· bsNone — форма не будет иметь текста заголовка, системного меню, кнопок минимизации, максимизации и закрытия,
· bsDialog — у формы будут присутствовать только системное меню и кнопка закрытия, размер формы нельзя изменять во время выполнения,
· bsSingle — у формы будут присутствовать все элементы управления, заданные другими свойствами формы, размер формы нельзя изменять во время выполнения,
· bsSizable — размеры формы можно изменять во время выполнения (значение по умолчанию),
· bsToolWindow — размеры формы нельзя изменять во время выполнения программы, форма имеет тонкую границу, у формы присутствует только кнопка закрытия. Системное меню отсутствует. Заголовок формы имеет высоту меньше обычного,
· bsSizeToolWin — вариант похож на задание bsToolWindow, при этом размер формы можно изменять.
|
Caption
|
Текст в заголовке окна.
|
ClientHeight
|
Высота клиентской части окна в пикселах.
|
ClientWidth
|
Ширина клиентской части окна в пикселах.
|
Color
|
Задает цвет фона формы. Значение выбирается из выпадающего списка.
|
Constraints
|
Задает ограничения на размер формы в пикселах. Подсвойствами являются:
· MaxHeight — максимальная высота формы, если указан ноль, размер не ограничивается,
· MaxWidth — максимальная ширина формы, если указан ноль, размер не ограничивается,
· MinHeight — минимальная высота формы, если указан ноль, размер не ограничивается,
· MinWidth — минимальная ширина формы, если указан ноль, размер не ограничивается.
|
Cursor
|
Задает вид курсора мыши, который появляется при наведении мыши на форму. Выбирается из выпадающего списка.
|
Enabled
|
Указывает, может ли форма принимать действия пользователя — щелчки мышью по кнопкам и элементам меню, ввод данных в поля Edit (значение по умолчанию true). Если задано false, то все диалоговые элементы формы блокируются.
|
Font
|
Задает характеристики шрифта для формы по умолчанию. Эти характеристики будут копироваться для всех компонентов, помещаемых на форму.
|
Height
|
Высота окна в пикселах.
|
Icon
|
Задает иконку, помещаемую в заголовок формы. При загрузке иконки вызывается обычное диалоговое окно выбора рисунка.
|
KeyPreview
|
Определяет, будут ли события нажатия пользователем клавиш перехватываться соответствующими событиями формы (значение true) или нет (значение по умолчанию false).
|
Left
|
Определяет положение на экране левого верхнего края окна в пикселах при старте формы по горизонтали.
|
Name
|
Имя формы. Создается при проектировании, не может изменяться во время выполнения программы.
|
Position
|
Задает положение и размер формы при ее первом выводе на экран. Может принимать следующие значения:
· poDefault — начальное положение и размер формы будут определяться операционной системой,
· poDefaultPosOnly — начальное положение формы будет определяться операционной системой,
· poDefaultSizeOnly — размер формы будет определяться операционной системой,
· poDesigned — начальное положение и размер формы будут такими же, как они были установлены при проектировании формы,
· poDesktopCenter и poScreenCenter — форма располагается в центре экрана,
· poMainFormCenter — форма располагается в центре главной формы,
· poOwnerFormCenter — форма располагается в центре родительской формы.
|
Top
|
Определяет положение на экране левого верхнего края окна в пикселах при старте формы по вертикали.
|
Visible
|
Задает, видима ли форма во время выполнения (значение true) или нет (false).
|
Width
|
Ширина окна в пикселах.
|
WindowState
|
Указывает, будет ли форма при начальном появлении на экране минимизированной, максимизированной или у нее будет размер, заданный при проектировании. Принимает следующие значения:
· Normal — форма имеет размер, заданный при проектировании,
· Minimized — форма будет минимизированной,
· Maximized — форма будет максимизированной, развернутой на весь экран.
|
Методы формы
Метод
|
Описание
|
Show
|
Вызывает на выполнение указанную форму. Таким методом можно вызвать произвольное количество экземпляров одной формы. В процессе выполнения программы можно переключаться между различными экземплярами формы.
|
ShowModal
|
Вызывает на выполнение форму в диалоговом, или в так называемом модальном, режиме. Переключиться на другую форму данного приложения невозможно, пока не будет закрыта модальная форма.
|
Close
|
Закрывает указанную форму. Если форма является главной в приложении, то завершается работа всего приложения.
|
Задачка на понимание №1
Основную идею задачек я подсмотрел у Александра Алексеева (более известного как GUNSMOKER), и подумал — а почему бы и мне не открыть такой подраздел, ибо
Delphi. Как указать папку "по умолчанию" для новых проектов
Надоело мне, что Delphi предлагает каждый новый проект сохранить в папке My documents. И задался я вопросом, а как бы эту папку изменить. Оказалось –
Delphi. Как указать папку "по умолчанию" для новых проектов
Надоело мне, что Delphi предлагает каждый новый проект сохранить в папке My documents. И задался я вопросом, а как бы эту папку изменить. Оказалось – очень просто. Настолько просто, что даже и рассказывать тут не о чем. Но я всё-таки расскажу так как я (почему-то) долгое время считал, что такой опции просто нет.
Главное меню –> Tools –> Options –> Environment Options –> Default Project
Или, с помощью IDE insight: Ctrl+. ввести default project + Enter
В Delphi XE-XE5 эти настройки хранятся в реестре:
HKEY_CURRENT_USERSoftwareEmbarcaderoBDS12.0GlobalsDefaultProjectsDirectory
Тип данных: REG_SZ
[[ This is a content summary only. Visit my website for full links, other content, and more! ]]
1. Начало работы с RAD Studio
В центре располагается форма, в левом нижнем углу — Инспектор объектов (Object Inspector), в правом нижнем углу — Панель инструментов (Tool Palette).
или нажать клавиши Shift+Ctrl+F9.
0. Введение
Приступим.
2. Пишем детскую программку под Android: основа
Продолжаем писать программку для детей под Android (требования мы сформулировали в первом посте). Начнём с того, что сделаем совсем простой проект – программку, которая умеет
2. Пишем детскую программку под Android: основа
Продолжаем писать программку для детей под Android (требования мы сформулировали в первом посте).
Начнём с того, что сделаем совсем простой проект – программку, которая умеет листать картинки при нажатии на кнопку. Картинки запакуем в ресурсы программы.
Создаём новый проект: Firemonkey Mobile application –> Blank application Разрешения
Отключим ненужные permissions. Так как по умолчанию включено слишком много всего.
Project –> Options –> Uses permissions. (Или через Help Insight: Ctrl+. –> ввести Permission + Enter, но это как-то странно работает). Сверху выберем All configurations Android Platform, так как список Permissions доступен только для Android платформы.
Как вы видите на скриншоте жирным false отмечены те настройки, у которых значение отличается от…
[[ This is a content summary only. Visit my website for full links, other content, and more! ]]
Delphi плюс Android? Есть идея! Tap#4
Эта заметка является продолжением предыдущих: Tap#1, Tap#2, Tap#3. И в ней я поговорю об анимации.
В моей будущей игре у персонажа будет два основных состояния. Назовём их “Открытый” и “Закрытый”. В первом состоянии внешний вид персонажа соответствует тому, который разработан в дизайнере и сохранён в переменной DesignPositions. Во втором, вид персонажа будет другой. Для робота я решил так: меняем цвет на серый, чуть-чуть уменьшаем общий размер, втягиваем ноги, руки и антенны, закрываем глаза.
Соответственно переход из состояния в состояние будет анимированным.
Делаю я следующим образом: сразу после создания фреймы, в методе SaveDesignPositions, произвожу необходимые трансформации и сохраняю положения и размеры объектов в переменную FClosedPositions. Вот так:
type TframeRobot = class(TNPC) private FClosedPositions: TDesignPositions; public procedure SaveDesignPositions; override; //... procedure TframeRobot.SaveDesignPositions; procedure SwitchToClose; const kBody = 9/10; kEye = 1/4; kAnt = 1/4; kHand = 5/6; kHand2 = 1/2; kLeg = 1/3; begin // HINT: мы смотрим роботу в лицо, поэтому левая рука - справа, правая - слева // уменьшаем Body Body.Position.X := Body.Position.X + Body.Width / 2 * (1 - kBody); Body.Width := Body.Width * kBody; Body.Position.Y := Body.Position.Y + Body.Height / 2 * (1 - kBody); Body.Height := Body.Height * kBody; // смещаем соединительные линии между телом и ногами LegLeftCon.Position.Y := LegLeftCon.Position.Y - LegLeftCon.Height * kBody; LegRightCon.Position.Y := LegRightCon.Position.Y - LegRightCon.Height * kBody; // уменьшаем Head Head.Position.X := Head.Position.X + Head.Width / 2 * (1 - kBody); Head.Width := Head.Width * kBody; Head.Position.Y := Head.Position.Y + Head.Height / 2 * (1 - kBody); Head.Height := Head.Height * kBody; // приближаем Head к Body HeadCenter.Position.Y := HeadCenter.Position.Y + Head.Height * (1 - kBody); // закрываем глазки EyeLeft.Position.Y := EyeLeft.Position.Y * kBody + EyeLeft.Height * kEye; EyeLeft.Height := EyeLeft.Height * kEye; EyeRight.Position.Y := EyeRight.Position.Y * kBody + EyeRight.Height * kEye; EyeRight.Height := EyeRight.Height * kEye; // уменьшаем и прячем антенны AntenaRight.Position.Y := AntenaRight.Position.Y * kBody + AntenaRight.Height * kBody; AntenaRight.Height := AntenaRight.Height * kBody * kAnt; AntenaRight.Position.Y := AntenaRight.Position.Y - AntenaRight.Height; AntenaLeft.Position.Y := AntenaLeft.Position.Y * kBody + AntenaLeft.Height * kBody; AntenaLeft.Height := AntenaLeft.Height * kBody * kAnt; AntenaLeft.Position.Y := AntenaLeft.Position.Y - AntenaLeft.Height; // прячем руки HandRightCenter.RotationAngle := 90; HandRightCenter.Position.X := HandRightCenter.Position.X + HandRight.Height * kHand; HandRightCenter.Position.Y := HandRightCenter.Position.Y + HandRight.Width * kHand2; HandLeftCenter.RotationAngle := -90; HandLeftCenter.Position.X := HandLeftCenter.Position.X - HandLeft.Height * kHand; HandLeftCenter.Position.Y := HandLeftCenter.Position.Y + HandLeft.Width * kHand2; // прячем ноги LegRightCenter.Position.Y := LegRightCenter.Position.Y - LegRight.Height * kLeg; LegLeftCenter.Position.Y := LegLeftCenter.Position.Y - LegLeft.Height * kLeg; end; begin inherited; SwitchToClose; FClosedPositions := TDesignPositions.Create; SavePositionsTo(FClosedPositions); end;
Здесь TframeRobot – это наш персонаж, про TNPC и SaveDesignPositions я писал в предыдущей заметке. Вот так выглядит наш робот до и после трансформации:
DesignPositions соответствуют картинке слева, ClosedPositions – картинке справа. Это начальное и конечное состояние в анимации. Сама анимация протекает во времени. Если взять начало времени за ноль, а конец – за единицу, то положение объекта легко рассчитать по формуле: f(t) = a + (b – a) * t, где t – время от 0 до 1, а – начальная координата, b – конечная координата, f – искомая координата. В библиотеке FMX такая функция уже реализована и называется InterpolateSingle.
Вот так у меня выглядит процедура для изменения размеров и положений объектов робота:
procedure TframeRobot.ProcessOpenCloseAnimation(const AProgress: Single); var BodyColor: TAlphaColor; i: Integer; CP, DP: TDesignPosition; AControl: TControl; begin BodyColor := InterpolateColor($FF99CC00, TAlphaColors.Gray, AProgress); // цикл от 1, т.к. саму фрейму масштабировать не надо for i := 1 to DesignPositions.Count - 1 do begin AControl := Controls[i]; CP := ClosedPositions.Items[i]; DP := DesignPositions.Items[i]; // цвет if (AControl is TShape) and (AControl <> EyeLeft) and (AControl <> EyeRight) then if TShape(AControl).Fill.Color <> TAlphaColorRec.Null then TShape(AControl).Fill.Color := BodyColor; // положение AControl.Position.X := InterpolateSingle(DP.Left, CP.Left, AProgress) * ScaleFactor; AControl.Position.Y := InterpolateSingle(DP.Top, CP.Top, AProgress) * ScaleFactor; // размер применяем ко всем, кроме "опорных" точек if Pos('Center', AControl.Name) = 0 then begin AControl.Width := InterpolateSingle(DP.Width, CP.Width, AProgress) * ScaleFactor; AControl.Height := InterpolateSingle(DP.Height, CP.Height, AProgress) * ScaleFactor; end; // поворот AControl.RotationAngle := InterpolateSingle(DP.RotationAngle, CP.RotationAngle, AProgress); end; end;
(Про ScaleFactor я писал в предыдущей заметке.)
Как видите, ничего тут сложного нет.
Теперь создаём TFloatAnimation-объект, назовём его faOpenClose:
object faOpenClose: TFloatAnimation Duration = 0.300000000000000000 OnProcess = faOpenCloseProcess PropertyName = 'OpenCloseValue' end
Далее у фреймы:
type TframeRobot = class(TNPC) .. procedure faOpenCloseProcess(Sender: TObject); private FOpenCloseValue: Single; FClosed: Boolean; .. public property OpenCloseValue: Single read FOpenCloseValue write FOpenCloseValue; .. procedure TframeRobot.faOpenCloseProcess(Sender: TObject); begin ProcessOpenCloseAnimation(FOpenCloseValue); end;
И осталось запустить анимацию в прямом:
procedure TframeRobot.CloseWithAnimation; begin FClosed := True; faOpenClose.Stop; faOpenClose.StartValue := 0; faOpenClose.StopValue := 1; faOpenClose.Start; end;
, либо обратном направлении:
procedure TframeRobot.OpenWithAnimation; begin FClosed := False; faOpenClose.Stop; faOpenClose.StartValue := 1; faOpenClose.StopValue := 0; faOpenClose.Start; end;
Ну и теперь, мы можем реализовать метод ScaleControls, который в прошлой заметке остался не реализованным. Выглядит он у меня так:
procedure TframeRobot.ScaleControls; procedure ScalePositions; begin // устанавливаем расположение контролов в зависимости от текущего состояния // (процедура анимации учтёт ScaleFactor) if FClosed then ProcessOpenCloseAnimation(1) else ProcessOpenCloseAnimation(0) end; procedure ScaleStrokeThickness; var i: Integer; begin for i := 1 to Length(Controls) - 1 do if Controls[i] is TShape then if TShape(Controls[i]).Stroke.Kind = TBrushKind.bkSolid then TShape(Controls[i]).Stroke.Thickness := 12 * ScaleFactor; end; procedure RecalcBodyRadius; begin Body.XRadius := (LegLeft.LocalRect.Width - LegLeft.Stroke.Thickness) / 2; Body.YRadius := Body.XRadius; end; procedure RecalcAntenaRadius; begin AntenaLeft.XRadius := (AntenaLeft.Width - AntenaLeft.Stroke.Thickness) / 2; AntenaLeft.YRadius := AntenaLeft.XRadius; AntenaRight.XRadius := AntenaLeft.XRadius; AntenaRight.YRadius := AntenaLeft.XRadius; end; begin ScalePositions; ScaleStrokeThickness; RecalcBodyRadius; RecalcAntenaRadius; end;
Заметка получилась больше, чем я предполагал, поэтому закругляюсь. Напоследок скажу, что кроме анимации по смене состояния, у меня будет ещё как минимум одна анимация. Анимация-приветствие. Всё вместе выглядит так: