−トップへ−

コンポーネントを動的に作成する

 フォームに設置するコンポーネントは,通常フォームの設計時に配置しますが,同じ働きをするコンポーネントなどを大量に使用する場合は,プログラムで作成した方が効率的なことがあります。
 以下に記すコードではパネルを作成していますが,この動的に作成する方法はすべてのコンポーネントに共通です。
 ここでは,フォームにボタンを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個生成されます。
 そして,それぞれのパネルはドラッグして動かすことができます。

−トップへ−