[Delphi:90617] コンポーネントの動的な生成

1,207 views
Skip to first unread message

Hirao

unread,
Aug 7, 2008, 9:25:17 PM8/7/08
to Del...@ml.users.gr.jp
Hiraoです。
いつも勉強させていただいております。

パネルの上にLabelとEditBoxを貼り付けます。
このパネルを複数個フォームに貼り付けたいのです。コピペでやればできますけど
これをプログラムの中で配列を作るように動的に生成してその1つづつを貼り付けたい
のです。
コンポーネントの配列とでもいいますか、そういう感じで扱いたいのです。
わかっていただけますでしょうか?

例)
//CNTは生成する個数
procedure HARITUKE(CNT:Integer);
var
i:Integer;
begin
for i:=0 to CNT-1 do begin
//生成してフォームに貼り付けする処理
end;

end;

どうすればできますでしょうか?
環境 WindwosXP(SP3)+Delphi 7 Ent版

純一

unread,
Aug 7, 2008, 10:01:20 PM8/7/08
to Del...@ml.users.gr.jp
金子です今日は

On Fri, 08 Aug 2008 10:25:17 +0900
Hirao <hi...@stannet.ne.jp> wrote:
> コンポーネントの配列とでもいいますか、そういう感じで扱いたいのです。

以前、動的にパネルやイメージを生成し利用したことがあります。その部分をそ
のまま貼り付けたので、余計な部分も多いですが、ご参考までに
環境:環境:CeleronD 3.06GH + 1GB RAM + XP Home SP2 + DP6 UP2


procedure TDispPanels.PanelSet(xPopupMenu: TPopupMenu;xData:TadoDataSet; xParent: TScrollBox);//xParent: TWinControl);
var
i,j,nh,shft:integer;
begin
try
GParent:=(xParent as TScrollBoxEx);
except

end;
yData:=xData;
yData.Open;
yData.Requery;
AfterSet:=False;
xDispFlg:=False;
xParent.VertScrollBar.Position:=0;
for i := 0 to PanelCount-1 do begin
if Labels[i]<>nil then
Labels[i].Free;
Labels[i]:=nil;
if Images[i]<>nil then
Images[i].Free;
Images[i]:=nil;
if Panels[i]<>nil then
Panels[i].Free;
Panels[i]:=nil;
end;
xMemo.Lines.Add('Finish Free');
PanelCount:=yData.RecordCount;
if PanelCount=0 then
exit;
c:=Ceil(Sqrt(PanelCount));
if c>3 then begin
c:=3;
gHPanelCount:=c;
nh:=Ceil(yData.RecordCount/c);
with xParent do begin
Align:=alNone;
w:=(Width -25 ) div c -2;
VertScrollBar.Visible:=True;
VertScrollBar.Range:=nh*w;
end;
end else begin
w:=xParent.Width div c;
nh:=c;
xParent.VertScrollBar.Visible:=False;
end;
SetLength(Images, c*nh+5);
SetLength(Panels, c*nh+5);
SetLength(Labels, c*nh+5);
xMemo.Lines.Add('SetLength');
for i:=0 to nh-1 do begin
for j := 0 to c-1 do begin
Panels[i*c+j]:=TPanel.Create(nil);
Labels[i*c+j]:=TLabel.Create(nil);
with Labels[i*c+j] do begin
Parent:=Panels[i*c+j];
Top:=1;
Left:=1;
Font.Size:=8;
Font.Color:=clRed;
end;
with Panels[i*c+j],yData do begin
OnMouseDown:=MouseDown;
PopupMenu:=xPopupMenu;
Top:=w*i;
Left:=w*j;
Height:=w;
Width:=w;
Parent:=xParent;
end;
end;
end;
xMemo.Lines.Add('Panel create');
with yData do begin
First;
while not Eof do begin
Images[RecNo-1]:=TImage.Create(nil);
Images[RecNo-1].Parent:=panels[RecNo-1];
Images[RecNo-1].OnMouseDown:=MouseDown;
Images[RecNo-1].PopupMenu:=xPopupMenu;
Next;
end;
end;
DrawEachPanel(xPopupMenu,xParent);
PanelCount:=yData.RecordCount;
end;

****************************
金子 純一
<kane...@nifty.com
****************************

中村 隆

unread,
Aug 7, 2008, 10:08:32 PM8/7/08
to Del...@ml.users.gr.jp
sampleです

procedure TForm1.Button1Click(Sender: TObject);
var
WrkTEdit : TEdit;
begin
WrkTEdit := TEdit.Create( Self );
WrkTEdit.Color := clWindow;
WrkTEdit.Height := 20;
WrkTEdit.ImeMode := imClose;
WrkTEdit.Left := 10;
WrkTEdit.MaxLength := 0;
WrkTEdit.Name := 'Edit111';
WrkTEdit.Parent := Form1;
WrkTEdit.Text := '';
WrkTEdit.Top := 10;
WrkTEdit.Visible := True;
WrkTEdit.Width := 200;

end;


On Fri, 08 Aug 2008 10:25:17 +0900
Hirao <hi...@stannet.ne.jp> wrote:

> __________ NOD32 3338 (20080807) 情報 __________
>
> このメールはNOD32によって検査済みです。
> http://canon-sol.jp
>

--
中村 隆 <taka...@csjpn.com>


石川元太郎

unread,
Aug 8, 2008, 9:37:48 PM8/8/08
to Del...@ml.users.gr.jp
Hiraoさん、こんにちは。
石川と申します。

ただパネルを生成するだけでは面白くないので、縦横にきれいに
整列するツールを作って遊んでみました。

サンプルでは3列×3行で幅をいろいろと変えて、ラベルとエディットが
載ったパネルを整列させています。

お尋ねの件に関しては、フォームのOnCreateイベントハンドラー内に
作成した関数_CreatePanelを参考にしてください。

コントロールを動的に生成する場合は、そのプロパティを自前で設定
しなければなりませんが、そのような場合私は、IDEのデザイナで
サンプルを作っておき、それをコピーしてIDEのエディタに貼り付けて
それを編集するようにしています。プロパティ名や値をタイプする手間が
省けますので・・・。


//**********************************
//メインフォームのユニット
//**********************************
unit FormMain;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
FEdits: array[1..9] of TEdit;
public
{ Public 宣言 }
end;

var
Form1: TForm1;

implementation

//レイアウトツールを定義したユニットを参照
uses GridLayout;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
//ラベルとエディットを含むパネルを返す関数
//Number:エディットの番号、1~9、配列FEditsの引数
function _CreatePanel(Number: Integer): TPanel;
var
edit: TEdit;
begin
//パネルの生成、オーナーはフォーム
Result := TPanel.Create(Self);
with Result do
begin
//描画の基準となる親はフォーム
Parent := Self;
Width := 150;
Height := 40;
//ラベルの生成、オーナーはフォーム
with TLabel.Create(Self) do
begin
//描画の基準となる親はパネル
Parent := Result;
Left := 8;
Top := 11;
Width := 24;
Height := 13;
Caption := 'Edit' + IntToStr(Number);
end;
//エディットの生成、オーナーはフォーム
edit := TEdit.Create(Self);
//配列に設定
FEdits[Number] := edit;
with edit do
begin
//描画の基準となる親はパネル
Parent := Result;
Left := 40;
Top := 8;
Width := 102;
Height := 21;
//パネルの幅が変更されるのでアンカーを設定
Anchors := [akLeft, akTop, akRight];
end
end;
end;

//OnCreateイベントハンドラーの本体
var
layout: TGridLayout;
count, x, y: Integer;
begin
//レイアウトツールを生成
layout := TGridLayout.Create;
try
//レイアウトの行と列を設定
layout.SetAxies([150, 120, 200], [40, 40, 40]);
//エディットの番号を初期化
count := 1;
for y := 0 to 2 do
for x := 0 to 2 do
begin
//パネルを生成して縦横に配置
layout.SetControlBouns(_CreatePanel(count), x, y, Succ(x), Succ(y));
Inc(count);
end;
finally
layout.Free;
end;
end;

end.

//**********************************
//レイアウトツールのユニット
//**********************************
unit GridLayout;

interface

uses
Windows, SysUtils, Classes, Controls;

type
TGridLayout = class
private
FAxisX: array of Integer;
FAxisY: array of Integer;
function Width(Left, Right: Integer): Integer;
function Height(Top, Bottom: Integer): Integer;
public
//レイアウトのグリッド座標を各列の幅と各行の高さで指定
procedure SetAxies(Widths, Heights: array of Integer);
//コントロールを列と行で配置
procedure SetControlBouns(Control: TControl;
Left, Top, Right, Bottom: Integer);
end;

implementation

{ TGridLayout }

function TGridLayout.Height(Top, Bottom: Integer): Integer;
begin
Result := FAxisY[Bottom] - FAxisY[Top];
end;

procedure TGridLayout.SetAxies(Widths, Heights: array of Integer);
var
i: Integer;
begin
SetLength(FAxisX, Succ(Length(Widths)));
FAxisX[0] := 0;
for i := 0 to Pred(Length(Widths)) do
FAxisX[Succ(i)] := FAxisX[i] + Widths[i];

SetLength(FAxisY, Succ(Length(Heights)));
for i := 0 to Pred(Length(Heights)) do
FAxisY[Succ(i)] := FAxisY[i] + Heights[i];
end;

procedure TGridLayout.SetControlBouns(Control: TControl; Left, Top, Right,
Bottom: Integer);
begin
Control.SetBounds(FAxisX[Left], FAxisY[Top],
Width(Left, Right), Height(Top, Bottom));
end;

function TGridLayout.Width(Left, Right: Integer): Integer;
begin
Result := FAxisX[Right] - FAxisX[Left];
end;

end.

//**********************************

長くなって申し訳ありませんでした。
それでは。

Hirao

unread,
Aug 10, 2008, 8:33:40 PM8/10/08
to Del...@ml.users.gr.jp
金子 さん、
中村 隆 さん、
石川 さん、

Hirao です。コメントありがとううございます。
皆さんから教えていただいたコードで試してみます。

今後ともよろしくお願いします。


Reply all
Reply to author
Forward
0 new messages