コンポーネントを動的に作成する
フォームに設置するコンポーネントは,通常フォームの設計時に配置しますが,同じ働きをするコンポーネントなどを大量に使用する場合は,プログラムで作成した方が効率的なことがあります。
以下に記すコードではパネルを作成していますが,この動的に作成する方法はすべてのコンポーネントに共通です。
ここでは,フォームにボタンを1個貼り付け,Button1Clickイベントハンドラを作成します。
private
{ Private 宣言 }
pnl:array[1..10] of Tpanel; //←これを書き込みます。
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer; //iを整数型の変数として宣言します
begin
//Panelを動的生成
for i:=1 to 5 do begin //パネルを5個作るために五回繰り返す。
pnl[i]:=Tpanel.Create(form1); //pnl[1]〜pnl[5]という名前で作成する。
pnl[i].Parent:=form1; //パネルをform1に作成する。
pnl[i].Left:=50+i*50; //パネルの左端(x座標)を50ピクセル間隔で並べる。
pnl[i].Top:=50; //パネルの上端(y座標)を50ピクセルにする。
pnl[i].Width:=40; //パネルの幅を40ピクセルにする。
pnl[i].Height:=40; //パネルの高さを40ピクセルにする。
end;
//Panelを動的生成終了
end;
これを実行すると,フォームに5個横に並んだ状態でパネルが表示されます。
これだけでは,ただ表示されるだけですので,これを動かせるようにしてみます。
まず,それぞれのパネルのイベントを作成するために,フォーム上にPanelコンポーネントを1つ貼り付けた後,
Panel1MouseDown
Panel1MouseMove
Panel1MouseUp
の3つのイベントハンドラを作成します。
unit sample1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Panel1: TPanel;
procedure Button1Click(Sender: TObject);
procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
//上のprocedure Panel1MouseDownをprocedure pnlMouseDownと書きかえます。
procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
//上のprocedure Panel1MouseMoveをprocedure pnlMouseMoveと書きかえます。
procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
//上のprocedure Panel1MouseUpをprocedure pnlMouseUpUpと書きかえます。
private
{ Private 宣言 }
pnl:array[1..10] of Tpanel;
//imageの動的生成
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
//iを整数型の変数として宣言します
begin
//Panelを動的生成
for i:=1 to 5 do begin
//パネルを5個作るために五回繰り返す。
pnl[i]:=Tpanel.Create(form1);
//pnl[1]〜pnl[5]という名前で作成する。
pnl[i].Parent:=form1;
//パネルをform1に作成する。
pnl[i].Left:=50+i*50;
//パネルの左端(x座標)を50ピクセル間隔で並べる。
pnl[i].Top:=50;
//パネルの上端(y座標)を50ピクセルにする。
pnl[i].Width:=40;
//パネルの幅を40ピクセルにする。
pnl[i].Height:=40;
//パネルの高さを40ピクセルにする。
pnl[i].OnMouseDown:=pnlMouseDown; //←これを書き加えます。
pnl[i].OnMouseMove:=pnlMouseMove; //←これを書き加えます。
pnl[i].OnMouseUp:=pnlMouseUp; //←これを書き加えます。
end;
//Panelを動的生成終了
end;
//以下の部分が新たに書かれた部分です。
//下の行の TForm1.Panel1MouseDown を TForm1.pnl1MouseDown と書きかえます。
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
end;
//下の行の TForm1.Panel1MouseMove をTForm1.pnl1MouseMove と書きかえます。
procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
end;
//下の行の TForm1.Panel1MouseUp を TForm1.pnl1MouseUp と書きかえます。
procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
end;
end.
ここまで作成したら,フォーム上に貼り付けたPanelコンポーネントを削除します。
次に,pnlMouseDown,pnlMouseMove,pnlMouseUpのイベントハンドラに下のようなプログラムコードを記述します。
unit sample1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Panel1: TPanel;
procedure Button1Click(Sender: TObject);
procedure
pnlMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure
pnlMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure
pnlMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private 宣言 }
pnl:array[1..10] of Tpanel;
//imageの動的生成
panelx,panely:integer; //←これを記述
mousedown:boolean; //←これを記述
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
//iを整数型の変数として宣言します
begin
//Panelを動的生成
for i:=1 to 5 do begin
//パネルを5個作るために五回繰り返す。
pnl[i]:=Tpanel.Create(form1);
//pnl[1]〜pnl[5]という名前で作成する。
pnl[i].Parent:=form1;
//パネルをform1に作成する。
pnl[i].Left:=50+i*50;
//パネルの左端(x座標)を50ピクセル間隔で並べる。
pnl[i].Top:=50;
//パネルの上端(y座標)を50ピクセルにする。
pnl[i].Width:=40;
//パネルの幅を40ピクセルにする。
pnl[i].Height:=40;
//パネルの高さを40ピクセルにする。
pnl[i].OnMouseDown:=pnlMouseDown;
//←これを書き加えます。
pnl[i].OnMouseMove:=pnlMouseMove;
//←これを書き加えます。
pnl[i].OnMouseUp:=pnlMouseUp;
//←これを書き加えます。
end;
//Panelを動的生成終了
end;
procedure TForm1.
pnlMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i:integer; //iを整数型の変数に宣言する
begin
for i:=1 to 5 do //pnl[1]からpnl[5]の,どのパネルでマウスが押されたか調べるために,1から5まで繰り返す
begin
if sender=pnl[i] then //sender=pnl[i]で押されたパネルがわかる。
begin
mousedown:=true; //mousedown:=trueでマウスが押されたことを認識させる
panelx:=x; //変数panelxにマウスが押されたパネルのx座標を代入
panely:=y; //変数panelyにマウスが押されたパネルのy座標を代入
exit;
end;
end;
end;
procedure TForm1.
pnlMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
i:integer; //iを整数型の変数に宣言する
begin
for i:=1 to 5 do
begin
if sender=pnl[i] then //MouseDownと同じように,どのパネルの上でマウスが動かされたのか調べる
begin
if mousedown=true then
begin
pnl[i].left:=pnl[i].left+x-panelx;
pnl[i].top:=pnl[i].top+y-panely;
end;
end;
end;
end;
procedure TForm1.
pnlMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
mousedown:=false; //マウスボタンが上がったことを認識させる
end;
end.
これを実行すると,ボタンを押すことで,パネルが5個生成されます。
そして,それぞれのパネルはドラッグして動かすことができます。