おばんさまです。
TControlを変数で指定したい。と思ったのですが、これは可能でしょうか?
con:=TControl(tedit).Create(form1);
のteditという部分を文字列でtbutton、tlistboxのように変数指定して使いたいのです。
var
s:string;
con:tcontrol;
begin
s:='tedit';
con:=TControl(s).Create(self);
end;
http://docwiki.embarcadero.com/Libraries/Tokyo/ja/System.Classes.FindClass
はどうですか?
ちょっと違うかもしれませんが、以下を応用できませんかね??
type
TForm1 = class(TForm)
Button1: TButton;
Panel1: TPanel;
Button2: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
c: array [0..2] of TControl;
〜〜〜〜〜
procedure TForm1.FormCreate(Sender: TObject);
begin
c[0] := Button1;
c[1] := Panel1;
c[2] := Label1;
end;
procedure TForm1.Button2Click(Sender: TObject);
const
ib: Byte = 0;
begin
inc(ib);
c[ib mod 3].Left := c[ib mod 3].Left + 10;
end;
こんな方法ではどうですか?
環境が書かれていなかったのですが、とりあえず DelphiXE8 で試してみました。
【 FMXの場合 】
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Controls.Presentation,
FMX.Edit, FMX.StdCtrls, FMX.Layouts, FMX.ListBox;
type
TForm1 = class( TForm )
procedure FormCreate ( Sender : TObject );
function CreateMyControl( Parent : TObject; AName : String ) : TControl;
private
{ private 宣言 }
MyControl : TControl;
public
{ public 宣言 }
end;
TTest = class( TControl );
var
Form1: TForm1;
implementation
{$R *.fmx}
// フォーム生成処理
procedure TForm1.FormCreate( Sender : TObject );
begin
// コントロール作成
MyControl := CreateMyControl( Self, 'TLabel' );
// MyControl := CreateMyControl( Self, 'TEdit' );
// MyControl := CreateMyControl( Self, 'TButton' );
// MyControl := CreateMyControl( Self, 'TListBox' );
// プロパティ設定
// ※ もちろんプロパティはキャストするクラスにより変わります。
TLabel( MyControl ).Width := 100;
TLabel( MyControl ).Height := 100;
TLabel( MyControl ).Position.X := 100;
TLabel( MyControl ).Position.Y := 100;
TLabel( MyControl ).Enabled := TRUE;
TLabel( MyControl ).Visible := TRUE;
TLabel( MyControl ).Text := 'KONNOYA';
end;
// コントロール生成処理
function TForm1.CreateMyControl( Parent : TObject; AName : String ) : TControl;
var
ClassFinder : TClassFinder;
AClass : TPersistentClass;
AControl : TControl;
begin
// クラスファインダー生成
ClassFinder := TClassFinder.Create;
try
// クラスを取得
AClass := ClassFinder.GetClass( AName );
AControl := AClass.NewInstance as TControl;
AControl.Create( Self );
AControl.Parent := Parent;
finally
// クラスファインダー解放
ClassFinder.DisposeOf;
end;
// コントロールを返す
Result := AControl;
end;
end.
【 VCLの場合 】
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Generics.Collections;
type
TForm1 = class( TForm )
procedure FormCreate ( Sender : TObject );
function CreateMyControl( Parent : TObject; AName : String ) : TControl;
private
{ Private 宣言 }
MyControl : TControl;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// フォーム生成時処理
procedure TForm1.FormCreate( Sender : TObject );
begin
// コントロール生成
MyControl := CreateMyControl( Self, 'TLabel' );
// MyControl := CreateMyControl( Self, 'TEdit' );
// MyControl := CreateMyControl( Self, 'TButton' );
// MyControl := CreateMyControl( Self, 'TListBox' );
// プロパティ設定
// ※ もちろんプロパティはキャストするクラスにより変わります。
TLabel( MyControl ).Width := 100;
TLabel( MyControl ).Height := 100;
TLabel( MyControl ).Left := 100;
TLabel( MyControl ).Top := 100;
TLabel( MyControl ).Enabled := TRUE;
TLabel( MyControl ).Visible := TRUE;
TLabel( MyControl ).Caption := 'KONNOYA';
end;
// コントロール生成処理
function TForm1.CreateMyControl( Parent : TObject; AName : String ) : TControl;
type
TPCDictionary = TDictionary< String, TPersistentClass >;
var
ClassList : TPCDictionary;
ClassFinder : TClassFinder;
AClass : TPersistentClass;
AControl : TControl;
begin
// ディクショナリ作成
ClassList := TPCDictionary.Create;
ClassList.Add( 'TLabel' , TLabel );
ClassList.Add( 'TEdit' , TEdit );
ClassList.Add( 'TButton' , TButton );
ClassList.Add( 'TListBox', TListBox );
// クラスを取得
ClassList.TryGetValue( AName, AClass );
AControl := AClass.NewInstance as TControl;
AControl.Create( Self );
AControl.Parent := Parent;
// コントロールを返す
Result := AControl;
end;
end.
VCLでは何故か TClassFinder が参照する FClassList.Items に
クラスのリストが格納されていない為、
自力でTDictionaryを作り、そこから探す様にしています。
ン
「文字列」というところにこだわるのでなければ、
トではまたはクラス参照型というものを使って「型」そのものを変数に入れることができます。
(ただしいきなり変数宣言はできなくて、まずヲサヲサでその型を作っておく必要がありますが)
ヲサヲサ
ヲサヲサヲサヲサヤテヤヲサスヲサヲサヲサヤテサヲサッッヲサ「ヤテクラスの型を表す型」を作ってョョョ
ヲサヲサ
ヲサヲサヲサヲサコヲサヤテヤサヲサッッヲサその型の変数を宣言する
ヲサヲサヲサヲサコヲサヤナサ
ヲサヲサヲサヲサコヲサヤツサ
ヲサヲサ
ヲサヲサヲサヲサヲサコスヲサヤナサ
ヲサヲサヲサヲサヲサコスヲサョティモゥヲサヲサヤナサヲサッッヲサヤナができる
ヲサヲサヲサヲサョミヲサコスヲサモサ
ヲサヲサヲサヲサヲサコスヲサヤツサ
ヲサヲサヲサヲサヲサコスヲサョティモゥヲサヲサヤツサヲサッッヲサヤツができる
ヲサヲサヲサヲサョミヲサコスヲサモサ
ヲサヲササ
ヤテの型を受け取る関数というのも作ることができますね。
ヲサヲサ
ヲサヲサヲサヲサヤテヤヲサスヲサヲサヲサヤテサ
ヲサヲサヲサテティコヲサヤテヤサヲサコヲサヤテゥコヲサヤテサ
ヲサヲサ
ヲサヲサヲサヲサメヲサコスヲサョティゥサ
ヲサヲササ
ヲサヲサョョョ
ヲサヲサヲサコスヲサテティヤナャヲサモゥヲサヲサヤナサ
ヲサヲサヲサコスヲサテティヤツャヲサモゥヲサヲサヤツサ