delphi - Delphi XE2 Firemonkey的Align属性设置为alScale如何影响坐标系?

标签 delphi delphi-xe2 firemonkey

Delphi XE2 Firemonkey 的 Align 属性设置为 alScale 对坐标系有何影响?

我正在研究 Firemonkey 的 Canvas 绘图功能,当组件的 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

最佳答案

align 属性影响 TShapes 后代、TControl 等,但不影响位图的内容。

您似乎在 TBitmap 上缓冲一些自定义绘图,然后将其分配给控件。 FMX 将无法重新对齐自定义绘图,因为它们没有封装在可对齐类中(它只是一些像素)。

您可以在调整控件大小时重新绘制“缓冲区”,并将其重新分配给其“主机”,以根据您的意愿调整绘图。或者也许不要释放“缓冲绘图”并在调整表单大小时对其进行转换/重新分配。

但更好的方法是使用形状系统,这与 FMX HD 的使用方式相匹配,对齐将是自动的。 因此,不要绘制一条线,而是在父对象内创建一条 TLine,并根据父控件对这条新线的对齐方式进行分层。

关于delphi - Delphi XE2 Firemonkey的Align属性设置为alScale如何影响坐标系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12133866/

相关文章:

delphi - sonar delphi插件自定义规则

delphi - 通过设置透明颜色来剪切火猴形状的一部分不起作用?

delphi - 我不断收到 "Invalid class typecast"错误,我不知道为什么

delphi - 将多边形缩小为 TPoint 数组?

algorithm - 不重复 N 个元素的组合,不使用 for..to..do

firebase - Firestore 身份验证用户

android - 带有字符串元素的 Delphi XE7 Android Record 无法编译

delphi - (delphi 应用程序)发现错误的位置

delphi - fatal error : Cannot create output file "project1.exe"

android - Android 版 Firemonkey 中的游戏循环