StyleBook Resources Text Editor 패치

2013.12.05 13:32
파이어몽키 스타일을 사용하면 매우 풍부하고 있어 보이게(?) 프로그램을 표현 할 수 있습니다.
스타일 수정 시 약간의 편리한 기능의 패치가 있어 소개합니다.

StyleBook Resources Text Editor

내용 : Style designer로만 편집 가능했던 Resource를 Text Editor에서 수정 가능
대상 : Delphi XE4 이상
패치방법 : 
 1) 아래 링크에서 다운로드
 2) 다운받은 *.bpl파일을 특정 위치(라이브러리 등)로 이동
 3) Components > Install Package > Add > 위의 *.bpl 선택

아래와 같이 Resource Property가 (Resource) > (TStrings)로 바뀌고 (TStrings) 더블클릭 시 String List Editor 윈도우가 호출 됩니다.(기존 (Resource) 더블 클릭 시 Style designer가 표시되었습니다.)
패치 후 StyleBook 아이콘을 더블 클릭하면 Style designer로 넘어갈 수 있습니다.
패치 이후 StyleBook Resource


험프리.김현수 파이어몽키 Firemonkey, StyleBook

[FMX] 다이나믹한 UI 효과 - Float animation effect

2013.03.05 16:35

대부분의 분들은 파이어몽키로 멀티플랫폼 지원을 위한 개발을 생각하고 계실텐데요.

파이어몽키는 멀티플랫폼 기능외에도 다양한 기능이 포함되어 있습니다.


대표적으로 

3D 효과 및 벡터형식의 부드러운 출력, RoateAngle 및 Scale 등의 신규 속성 등이 추가되었습니다.


오늘은 

새로운 기능 중 하나인 FloatAnimation에 대해 소개하려 합니다.


FloatAnimation은 단어 그대로 Float을 Animation하는 놈입니다.


좀 더 자세히 설명하면, 

지정한 Start와 Stop에 해당하는 Float 값사이를 지정된 시간(Duration)에 맞춰 다양한 효과(Interpolation: 보간)로 값을 변경하는 놈입니다.


우선 샘플을 보시면 아래의 영상은 마우스 휠(업/다운) 시 마우스 주변에 효과를 주고. 특정 Zoom 이상인 경우 RoundRect 메시지를 표시하고 서서히 사라지는 효과를 주었습니다.

(구현 내용은 아래 첨부한 소스파일을 참고하시구요.)


FloatAnimation은 TAniThread(FMX.Types.pas)에 의해 쓰래드로 진행이 되어 

다른작업에 영향을 주지 않고도 UI에 다양한 효과 및 재미난 기능을 매우 쉽게 넣을 수 있습니다.


FloatAnimation을 사용하는 방법은 두가지 인데요.


첫째, 

애니메이션 효과를 줄 컨트롤의 자식으로 TFloatAnimation을 등록 후 설정하여 사용하는 방법

둘째,

애니메이션 효과를 줄 컨트롤에 .AnimationFloat() 메소드를 이용하여 직접 효과를 주는 방법


두개 중 편리한 방법을 사용하시면 될 것 같습니다.


아래의 영상은

AnimationType과 TInterpolationType을 지정하고 어떤 효과가 나는지 확인하는 샘플입니다.

(당겼다가 가기[Back], 공튀기기[Bounce] 등의 효과를 확인 할 수 있습니다.)


그리고 위 영상의 주요코드


uses
  System.TypInfo;

procedure TForm3.FormCreate(Sender: TObject);
var
  Animation: TAnimationType;
  Interpolation: TInterpolationType;
begin
  Circle1.Position.X := 0;
  Circle1.Position.Y := (Panel1.Height - Circle1.Height) / 2;

  // Circle이 멈출 위치를 계산
  FLastValue := Panel1.Width - Circle1.Width;

  // 콤보박스에 속성을 표시합니다.
  for Animation in [Low(TAnimationType)..High(TAnimationType)] do
    cbbAnimation.Items.AddObject(GetEnumName(TypeInfo(TAnimationType), Ord(Animation)), TObject(Animation));
  cbbAnimation.ItemIndex := 0;

  for Interpolation in [Low(TInterpolationType)..High(TInterpolationType)] do
    cbbInterpolation.Items.AddObject(GetEnumName(TypeInfo(TInterpolationType), Ord(Interpolation)), TObject(Interpolation));
  cbbInterpolation.ItemIndex := 0;
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
  if rbTFloatAnimation.IsChecked then
  begin
    FloatAnimation1.PropertyName := 'Position.X';
    FloatAnimation1.StartValue := 0;
    FloatAnimation1.StopValue := FLastValue;
    FloatAnimation1.Duration := 1;
    FloatAnimation1.AnimationType := TAnimationType(cbbAnimation.Items.Objects[cbbAnimation.ItemIndex]);
    FloatAnimation1.Interpolation := TInterpolationType(cbbInterpolation.Items.Objects[cbbInterpolation.ItemIndex]);
    FloatAnimation1.Start;
  end
  else
  begin
    Circle1.Position.X := 0;
    Circle1.AnimateFloat(
        'Position.X',
        FLastValue,
        1,
        TAnimationType(cbbAnimation.Items.Objects[cbbAnimation.ItemIndex]),
        TInterpolationType(cbbInterpolation.Items.Objects[cbbInterpolation.ItemIndex])
    );
  end;
end;

사용방법은 어렵지 않습니다.

그래도 다양한 효과를 위해서는 TInterpolationType과 TAnimationType을 잘 설정해 주어야 합니다.

글로 설명하는 것 보다 샘플프로그램 다운로드하셔서 실행해 보시는게 좋을 것같네요.


샘플프로그램 실행파일 

FloatAnimation.zip


샘플프로그램 소스파일

FloatAnimationSrc.zip


경고창 애니메이션 효과 소스

ThAlertAnimation.pas

Zoom 애니메이션 효과 소스

ThZoomAnimation.pas


아래는 엠바카데로의 도움말입니다. 참고하세요.


http://docwiki.embarcadero.com/Libraries/XE3/en/FMX.Types.TInterpolationType

Value Meaning

itLinear

A linear interpolation. The property value this animation applies to changes constantly over time.

itQuadratic

A quadratic function is applied to the path between the start and stop points. The slope of the path is zero at the start point and increases constantly over time. A scalar is applied to the function to make the endpoint fall on the path.

itCubic

The interpolation is of the form y = x**3. The slope of the path is zero at the start point and increases much faster than the quadratic function over the path.

itQuartic

The interpolation is of the form y = x**4. The slope of the path is zero at the start point and increases much faster than the quadratic function over the path.

itQuintic

The interpolation is of the form y = x**5. The slope of the path is zero at the start point and increases much faster than the quadratic function over the path.

itSinusoidal

The interpolation is of the form y = sin(x). The slope of the path is zero at the start point and places the first inflexion of the sin curve (x=pi) at the stop point.

itExponential

The interpolation is of the form y = e**x. The slope of the path is one at the start point and increase much faster than the quadratic function over the path.

itCircular

The path between the start and stop point for this interpolation is a quarter of a circle. The slope of the path is zero at the start point and verticle at the stop point.

itElastic

The path does not follow a geometric interpolation. The value (y coordinate) may decrease, moving back toward the Start Value, but time (x value) must always move in a positive direction.

itBack

The path does not follow a geometric interpolation. The value (y coordinate) may decrease, moving back toward the Start Value, but time (x value) must always move in a positive direction.

itBounce

The path depicts a bouncing ball. The path is made up of circular curves with curvature away from the straight line that connects the start and stop points. These curves are connected by sharp points.


http://docwiki.embarcadero.com/Libraries/XE3/en/FMX.Types.TAnimationType

Value Meaning

atIn

The curve that applies to the TInterpolationType for this animation starts at the starting value of the property animated.

atOut

The curve that applies to the TInterpolationType for this animation starts at the ending value of the property animated and proceeds backwards to the starting value.

atInOut

The curve that applies to the TInterpolationType for this animation starts at both the starting value and the ending value of the property animated and meets at the center point.


험프리.김현수 파이어몽키 Animation Effect, AnimationFloat, Dynamic UI, Firemonkey, FloatAnimation, FMX, 파이어몽키

메인폼을 얼리지 않고(Idle 상태) 대기하기.(TStopWatch 활용)

2013.02.28 13:13

볼랜드포럼에 Firemonkey 포럼이 생겨서 기분이 좋습니다. 룰루랄라 합니다.


그래서 좋은 강좌를 남기고 싶은데 별로 아는게 없어서 쿨럭...

그래서 팁이라도 남깁니다.


이번에도 Unittest하며 필요해서 만들어 본것입니다.


OpenDialog를 열고 파일경로를 입력해서 파일을 선택하는 Test 작성 중

OpenDialog.execute하면 바로 열리지가 않죠?


그래서 열릴때까지 대기를 해야 합니다.

Sleep을 주었지요. 하지만 Sleep이 제어권을 놓지 않아 Sleep이 끝나고 창이 열립니다.


그래서 좀 쉬며 기다리게 하려고 봤더니

Firemonkey에서는 GetTickCount 등을 WinAPI를 사용하면 안되지요.

그래서 찾은 놈이 StopWatch입니다.


아래는 제어권을 갖지 않고 대기하는 코드입니다.


uses
  System.Diagnostics;

procedure TTestLib.Delay(ms: Integer);
var
  StopWatch: TStopWatch;
begin
  StopWatch := TStopWatch.Create;

  StopWatch.Start;
  repeat
    Application.ProcessMessages;
    Sleep(1);
  until StopWatch.ElapsedMilliseconds >= ms;
end;


감사합니다. 끝~

험프리.김현수 파이어몽키

[FM2] XE3.FM2에서 Control을 Bitmap으로 내보내기 및 Bitmap.Pixels 사용하기

2012.10.04 20:49

Firemonkey2로 버전업 된 후로 참 많은 것이 변했습니다.


TControl은 말할 것도 없고 TBitmap도 많은 내용이 변했네요.


Unit test에서 특정 Pixel의 색상을 얻어오고자 할때 기존 Bitmap.Pixels이 없어진 것을 확인 후 깜짝 놀랐습니다.


자... 그럼 제가 삽질로 얻어온 내용을 공유하도록 합니다.


| Control을 Bitmap(TImage)으로 내보내기

var
  Bitmap: TBitmap;
  Map: TBitmapData;
begin
  Bitmap :=  TBitmap.Create(Round(Panel1.Width), Round(Panel1.Height));
  try
    Bitmap.Canvas.BeginScene;

    // Bitmap으로 내보내기
    Bitmap.Assign(Panel1.MakeScreenshot);
 
    // Pixel의 값을 원하실 때는 이렇게
    Bitmap.Map(TMapAccess.maRead, Map);
    //AlphaColor := Map.GetPixel(Round(X), Round(Y));
    Bitmap.Unmap(Map);
    Bitmap.Canvas.EndScene;

    Image1.Bitmap.Assign(Bitmap);
  finally
    Bitmap.Free;
  end;
end;


Panel1의 화면을 Bitmap으로 내보내는 코드 입니다.

특정 좌표의 값은 Map.GetPixel로 얻어오실 수 있구요 반환은 TAlphaColor 입니다.


TBitmapData라는 구조체를 이용하는군요 구글링에도 없는 따끈한 정보입니다. 실은 많이 안찾아 봣습니다. -_-;

험프리.김현수 파이어몽키 Bitmap.Pixels, Delphi, Fm2, FMX, TBitmapData, XE3, 태그를 입력해 주세요.

[FMX] Firemonkey 구조 - 어떻게 하나의 코드로 여러 플랫폼에서 실행 될까?

2012.06.23 03:04

이번에는 이리저리 파이어몽키 소스 보며 익혔던 간단한 구조에 대해 설명하려 합니다.

(딱, 제가 아는 만큼만 소개합니다.^^)


파이어몽키는 멀티 플랫폼을 지원하는 델파이 프레임웤 입니다.

어떻게 파이어몽키는 하나의 소스로 여러개의 플랫폼을 지원할까요?

여러개의 플랫폼을 지원하는 열쇠는 FMX.Platform.pas의 Platform: TPlatform에 있습니다.
(C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\source\fmx에 소스파일이 있습니다.)


FMX.Platform의 TPlatform 클래스를 보시면 대부분(거의 다)이 추상메소드(virtual; abstract;) 입니다. 구현이 안되어 있다는 것이죠.

그리고 메소드명이 상당히 플랫폼에 종속적인 냄새를 풍깁니다.

CreateWindow(창을 생성하는 건 OS에서 해주겠죠.)
CreateTimer(타이머도 OS에서 이벤트를 발생해 줍니다.)
WaitMessage(메시지 처리도 OS와 연관이 있지요.) 등등 모두 플랫폼에 종족적인 메소드들입니다.

그리고 소스 디렉토리에 보시면 FMX.Platform.Win과 FMX.Platform.Mac 두개의 플랫폼 관련 유닛파일을 보실 수 있습니다.

즉, FMX.Platform의 TPlatform을 상속받은 클래스들이 구현되어 있겠죠.

맞습니다. 각 파일을 보시면 TPlatformWin과 TPlatformCocoa 두개의 클래스가 TPlatform을 상속받습니다.

물론 추상메소드들도 모두 구현되어 있습니다.

TPlatformWin은 Windows API를 이용하여 구현이 되어 있고, TPlatformCocoa는 OS X API로 구현이 되어 있습니다.


그럼 어떻게 Firemonkey는 플랫폼에 맞는 TPlatform 객체를 사용할까요?

위의 질문에 답하기 위해 먼저 프로젝트 소스파일을 들여다 보겠습니다.

Delphi XE2에서 <Firemonkey HD Application> 프로젝트를 생성하시면 아래와 같은 소스코드를 기본적으로 생성합니다.

program Project1;

uses
  FMX.Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

위의 프로젝트 소스를 보면 도무지 참조하는 유닛이 FMX.Forms 밖에 없습니다.


그럼 FMX.Forms 유닛을 살펴보겠습니다.

주욱 보시면 VCL에서도 익숙한 TApplication, 앞으로 친하게 지내야될 TCommonCustomForm 등등의 클래스 등이 보입니다.

그리고 제일 아래에 보면 우리가 찾던 Platform 관련된 코드가 보입니다.

initialization
  RegisterFmxClasses([TApplication], [TApplication]);
  Screen := TScreen.Create(nil);
  Platform := PlatformClass.Create(nil);
  System.Classes.RegisterFindGlobalComponentProc(FindGlobalComponent);

finalization
  System.Classes.UnregisterFindGlobalComponentProc(FindGlobalComponent);
  FreeAndNil(Screen);
  // Platform global is freed in FMX.Types

위 코드의 4번째 줄을 보시면

Platform := PlatformClass.Create(nil);

이라고 PlatformClass를 이용해 TPlatform 객체를 생성해 할당합니다.


자 그럼 다시 PaltformClass를 따라가 봅니다.

FMX.Platform.pas에 PlatformClass 함수가 구현되어 있습니다.

function PlatformClass: TPlatformClass;
begin
  Result := ActualPlatformClass;
end;

그럼 ActualPlatformClass는 어디에 구현되어 있을까요?


예상하시는 분들도 있겠지만 위에서 설명한 Platform별 유닛(FMX.Platform.Win, FMX.Platform.Mac)에 구현되어 있습니다.

MSWINDOWS의 경우 TPlatformWin을 반환하고

MACOS의 경우 TPlatformCocoa를 반환합니다.

근데 의문이 듭니다. 어떻게 델파이는 2개중에 하나를 선택할까요?

그건 바로 Conditional define($IFDEF)을 이용합니다.

FMX.Platform의 구현부(implementation) 시작을 보시면 아래와 같은 코드를 보실 수 있습니다.

{$IFDEF IOS}
uses
  FMX.Platform.iOS, FMX.Canvas.iOS, FMX.Context.GLES;
{$ENDIF}

{$IFDEF MACOS}
uses
  FMX.Platform.Mac, FMX.Canvas.Mac, FMX.Context.Mac;
{$ENDIF}

{$IFDEF MSWINDOWS}
uses
  FMX.Platform.Win, FMX.Context.DX9;
{$ENDIF}

보시면 아시겠지만 IOS, MACOS, MSWINDOWS 별로 다른 유닛을 참조하도록 되어있습니다.

위의 3가지는 모두 Firemonkey가 지원하는 플랫폼입니다.

즉 Project Manager의 Target platform에서 Platform을 선택하면 그에 맞는 값(IOS, MACOS, MSWINDOWS)이 내부적으로 정의됩니다.

그래서 결국은 Target platform에 맞는 TPlatform 객체를 이용하여 OS에 맞는 API를 사용하여 실행됩니다.


좀더 설명을 하자면 위의 프로젝트 소스를 보시면 아래와 같이 Application을 실행(RUN)하는 코드를 볼 수 있습니다.

Application.Run;

Run 메소드를 살펴보면 아래와 같이 Platform에 따른 코드를 사용하여 Application을 실행합니다.

procedure TApplication.Run;
begin
  FRunning := True;
  AddExitProc(DoneApplication);
  try
    Platform.Run; // Platform의 Run 실행
  finally
    FRunning := False;
  end;
end;

// MSWINDOWS에 맞게 Application 실행
procedure TPlatformWin.Run;
begin
  { checking for canvas }
  if GlobalUseDirect2D then
    SetD2DDefault;

  Application.RealCreateForms;
  repeat
    try
      Application.HandleMessage;
    except
      Application.HandleException(Self);
    end;
  until Application.Terminated;
end;

// MACOS 맞게 Application 실행
procedure TPlatformCocoa.Run;
begin
  Application.RealCreateForms;
  CreateApplicationMenu;
  FRunLoopObserver := CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, True, 0, RunLoopObserverCallback, nil);
  CFRunLoopAddObserver(CFRunLoopGetCurrent, FRunLoopObserver, kCFRunLoopCommonModes);
  NSApp.Run;
end;

다른 메서드 또는 다른 유닛(FMX.Types 등)에서 Platform 전역변수를 이용하도록 구현되어 있습니다.


다시한번 정리하면, 

1, Project 소스에서 FMX.Forms 참조(uses)

2, FMS.Forms의 Initialization에서 FMS.Platform.pas 유닛의 PlatformClass를 통해 Platform 생성

3, FMS.Platform는 각 플랫폼 유닛의 ActualPlatformClass 함수 호출하여 Platform에 맞는 TPlatform 객체 형 방ㄴ환

4, 단, Platform에 맞는 유닛을 $IFDEF를 이용하여 결정($IFDEF는 Target platform 선택 시 정의)


이상으로 Firemonkey에서 Platform에 맞게 실행되는 구조를 두서없이 설명했습니다.

감사합니다. 끝~


PS - 다음에는 Firemonkey를 실질적으로 사용하기 위한 팁들을 몇개 소개하겠습니다.^^

험프리.김현수 파이어몽키 Firemonkey, FMX, FMX 구조, multi platform

[FMX,VCL 비교] #1 VCL의 Canvas와 FMX의 Canvas 차이

2012.06.20 12:52

파이어몽키로 작업하다보면 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.



험프리.김현수 파이어몽키 Canvas, Firemonkey, FMX, FMX VCL 차이, 파이어몽키

[FMX] 컨트롤(TPanel)등에 Form 넣기.

2012.03.23 12:45
Delphi XE2의 FireMonkey에서는 

TForm이 TControl을 상속 받지 않아 TPanel등에 Embed 할 수 없습니다.

위 방식으로 구현된 많은 샘플코드들을 Firemonkey에서 사용하지 못해 당황하다.
아래와 같은 방법으로 해결(?: 꼼수)하여 공유합니다..
// AForm을 AParent에 Embed
procedure EmbedForm(AParent: TControl; AForm: TCustomForm);
begin
  while AForm.ChildrenCount > 0 do
    AForm.Children[0].Parent := AParent;
end;

정상적으로 말하면 Embed는 아니고 Form에 있는 컨트롤들을 Panel로
부모를 옮겨 버리는 방식입니다.
 
사용방법은
  EmbedForm(Panel1, TForm1.Create(Self));


험프리.김현수 파이어몽키

  1. Blog Icon
    이회원

    panel1에 생성을 한 폼을 어떻게 close 시켜야 하나요? 그냥 free해도 남아 있던데.

[FMX] Firemonkey에서 ODS 사용하기

2012.02.17 16:18
Firemonkey는 아무래도 Cross platform이다 보니 윈도우 API를 사용하는

OutputDebugString 등을 사용할 수 없습니다. 
근데, 너무 불편해요 ODS가 없으면 그래서 찾아보니

Window API를 사용할 수 있네요...
그것도 간단하게

uses에 Winapi.Windows를 추가하면 됩니다.
그리고 아래와 같이 예외(IFDEF)하시고 사용하시면

혹시 다른 플랫폼에서 문제가 생길 염려는 없겠죠^^

{$IFDEF MSWINDOWS}
  OutputDebugString(PChar(Format('우왕 ODS가 된다.', [])));
{$ENDIF}

끝~

험프리.김현수 파이어몽키