파이어몽키로 작업하다보면 VCL과의 차이점으로 어려움을 겪는 경우가 많습니다.
그동안 작업하며 습득한 차이점을 한가지한가지 풀어놓으려 합니다.
그중 첫번째 Canvas 입니다.
일반적으로 TImage에 Drawing을 하는 예제로 구성하였습니다.
VCL과 FMX의 동일한 기능을 구현했으니 비교해 보시면 좋을 것 같습니다.
FMX 코딩시 주의점
1, TImage.Picture.Bitmap => TImage.Bitmap : VCL의 Picture 객체가 빠졌습니다.
2, Bitmap.Canvas.BeginScene ~ EndScene, Bitmap.BitmapChange : Canvas에 그리기고 화면에 표시하기 위한 절차입니다.
3, Brush => Fill, Pen => Stroke 등으로 속성들이 약간씩 변했습니다.
4, MoveTo, LineTo => DrawLine
5, FMX의 기본적인 좌표가 Single 형이기 때문에 Bitmap의 Pixel 단위인 Integer로 형변환(Round, Trunc)이 필요합니다.
이하 소스코드 입니다. 빈프로젝트에 아래 소스 복사하면 컴파일 됩니다.(Unit명만 주의) 폼에 컨트롤이 없습니다.
| VCL Canvas Freeline Draw
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } FDownPos: TPoint; FImage: TImage; procedure MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin FImage := TImage.Create(Self); FImage.Parent := Self; FImage.Align := alClient; FImage.OnMouseDown := MouseDown; FImage.OnMouseMove := MouseMove; FImage.Picture.Bitmap.SetSize(FImage.Width, FImage.Height); FIMage.Picture.Bitmap.Canvas.Brush.Color := clBlack; FImage.Picture.Bitmap.Canvas.FillRect(FImage.ClientRect); FImage.Visible := True; end; procedure TForm1.MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if ssLeft in Shift then FDownPos := Point(X, Y); end; procedure TForm1.MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if ssLeft in Shift then begin with FImage.Picture.Bitmap.Canvas do begin Pen.Color := clRed; Pen.Width := 3; MoveTo(FDownPos.X, FDownPos.Y); LineTo(X, Y); end; FDownPos := Point(X, Y); end; end; end.
| FMX Canvas Freeline Draw
unit Unit2; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Objects; type TForm2 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } FDownPos: TPointF; FImage: TImage; procedure MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); procedure MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); public { Public declarations } end; var Form2: TForm2; implementation {$R *.fmx} procedure TForm2.FormCreate(Sender: TObject); begin FImage := TImage.Create(Self); FImage.Parent := Self; FImage.Align := TAlignLayout.alClient; FImage.OnMouseDown := MouseDown; FImage.OnMouseMove := MouseMove; FImage.Bitmap.Create(Round(FImage.Width), Round(FImage.Height)); FImage.Bitmap.Canvas.BeginScene; FImage.Bitmap.Canvas.Fill.Color := claBlack; FImage.Bitmap.Canvas.FillRect(FImage.ClipRect, 0, 0, AllCorners, 1); FImage.Bitmap.Canvas.EndScene; FImage.Visible := True; end; procedure TForm2.MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin if ssLeft in Shift then FDownPos := PointF(X, Y); end; procedure TForm2.MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); begin if ssLeft in Shift then begin with FImage.Bitmap.Canvas do begin BeginScene; Stroke.Color := claRed; StrokeThickness := 3; DrawLine(FDownPos, PointF(X, Y), 1); EndScene; end; FImage.Bitmap.BitmapChanged; FDownPos := PointF(X, Y); end; end; end.