Delphi XE2 Firemonkey的Align属性设置为alScale如何影响坐标系?
我正在研究Firemonkey的画布绘制功能,并在组件的Align属性设置为alScale时遇到坐标系统的问题。以下演示程序(FM HD应用程序)说明了该问题。 编译并运行示例代码,绘制几行,然后更改表单的大小以便开始奇怪。这些线不会出现在预期的位置。
任何建议和解释都将不胜感激!提前谢谢。
主要表单(LineDrawFormUnit.pas):
unit LineDrawFormUnit;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Objects;
type
TLineDrawForm = class(TForm)
Image1: TImageControl;
Panel1: TPanel;
Label1: TLabel;
Label2: TLabel;
lX: TLabel;
lY: TLabel;
{ These event handlers are set in the IDE's object inspector }
procedure Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
procedure Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
{ This event handler is set/unset with the MouseDown and MouseUp events to capture mouse moves when drawing }
procedure ImageControl1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
procedure FormCreate(Sender: TObject);
private
FSaveBitmap: TBitmap;
p1, p2: TPointF; { Start and end points of lines to draw }
end;
var
LineDrawForm: TLineDrawForm;
implementation
{$R *.fmx}
procedure TLineDrawForm.FormCreate(Sender: TObject);
begin
Image1.Bitmap.Create(Round(Image1.Width), Round(Image1.Height));
end;
procedure TLineDrawForm.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,
Y: Single);
begin
p1.X := X;
p1.Y := Y;
lX.Text := FloatToStr(X);
lY.Text := FloatToStr(Y);
FSaveBitmap := TBitmap.Create(Image1.Bitmap.Width, Image1.Bitmap.Height);
FSaveBitmap.Assign(Image1.Bitmap); { Save the current canvas as bitmap }
Image1.OnMouseMove := ImageControl1MouseMove; { Activate the MouseMove event handler}
end;
procedure TLineDrawForm.ImageControl1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
begin
p2.X := X;
p2.Y := Y;
lX.Text := FloatToStr(X);
lY.Text := FloatToStr(Y);
Image1.Bitmap.Assign(FSaveBitmap);
Image1.Bitmap.Canvas.BeginScene;
try
Image1.Bitmap.Canvas.Stroke.Color := claGray;
Image1.Bitmap.Canvas.StrokeThickness := 0.5;
Image1.Bitmap.Canvas.DrawLine(p1, p2, 1.0);
finally
Image1.Bitmap.Canvas.EndScene;
Image1.Bitmap.BitmapChanged;
end;
end;
procedure TLineDrawForm.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,
Y: Single);
begin
p2.X := X;
p2.Y := Y;
lX.Text := FloatToStr(X);
lY.Text := FloatToStr(Y);
Image1.Bitmap.Canvas.BeginScene;
try
Image1.Bitmap.Canvas.Stroke.Color := claBlack;
Image1.Bitmap.Canvas.StrokeThickness := 2;
Image1.Bitmap.Canvas.DrawLine(P1, P2, 1.0);
finally
Image1.Bitmap.Canvas.EndScene;
Image1.Bitmap.BitmapChanged;
end;
(Sender as TControl).OnMouseMove := nil;
if FSaveBitmap <> nil then
FSaveBitmap.Free;
end;
end.
FMX文件(LineDrawFormUnit.fmx):
object LineDrawForm: TLineDrawForm
Left = 0
Top = 0
Caption = 'Polygon Form'
ClientHeight = 513
ClientWidth = 650
Visible = False
OnCreate = FormCreate
StyleLookup = 'backgroundstyle'
object Image1: TImageControl
Align = alScale
Position.Point = '(18,21)'
Width = 620.000000000000000000
Height = 452.000000000000000000
OnMouseDown = Image1MouseDown
OnMouseUp = Image1MouseUp
TabOrder = 0
end
object Panel1: TPanel
Align = alBottom
Position.Point = '(0,480)'
Width = 650.000000000000000000
Height = 33.000000000000000000
TabOrder = 2
object Label1: TLabel
Position.Point = '(16,8)'
Width = 25.000000000000000000
Height = 15.000000000000000000
TabOrder = 1
Text = 'X:'
end
object Label2: TLabel
Position.Point = '(384,8)'
Width = 25.000000000000000000
Height = 15.000000000000000000
TabOrder = 2
Text = 'Y:'
end
object lX: TLabel
Position.Point = '(32,8)'
Width = 313.000000000000000000
Height = 15.000000000000000000
TabOrder = 3
Text = '0'
end
object lY: TLabel
Position.Point = '(424,8)'
Width = 209.000000000000000000
Height = 15.000000000000000000
TabOrder = 4
Text = '0'
end
end
end
答案 0 :(得分:1)
align属性会影响 TShapes 后代, TControl 等,但不会影响位图的内容。
您似乎在TBitmap上缓冲了一些自定义绘图,然后将其分配给控件。 FMX将无法重新排列自定义绘图,因为它们未封装在可对齐的类中(它只是一些像素)。
您可以在调整控件大小时重绘“缓冲区”,并将其重新分配给“主机”以根据您的意愿调整图形。或者也许不要释放“缓冲的图纸”并在调整表单大小时对其进行转换/重新分配。
但更好的方法是使用形状系统,对齐方式将是自动的,这与FMX HD的使用方式相匹配。 因此,不是绘制一条线,而是在父对象中创建一个TLine,并根据父控件对该新行的对齐进行分层。