コンポーネントの配列化

解決


初心者M  2004-08-03 21:24:16  No: 10205

教えてください。VB経験者で現在「使いながら覚えるDELPHI3入門」を読みながら勉強しています。この本の中でLabel、Edit,TrackBarなどのコンポーネントを規則正しく並べて配置するのに全部手で幾つも作って配置する例が載っていました。VBだと「コントロール配列」で自在に数を増減させたりできますのでこのアイデアをDELPHIで適用しようと思いHELPを見たのですが分かりませんでした。

1.これを配列で管理できるのでしょうか?
2.出来ないとすると、例えば未知の人数に対応するLabelなどをソフト上で増減させる方法を教えてください。


TtPIPICH  URL  2004-08-03 22:50:02  No: 10206

るるとん@Kです
後者は
var
i:integer;
l:array[0..9] of TLabel
begin
for i:=0 to 9 do
l[i]:=TLabel.create;
end;


TtPIPICH  2004-08-03 22:51:22  No: 10207

.create(Self)かもしれません
実際にはParentや座標も指定しなければいけません


初心者M  2004-08-04 01:15:32  No: 10208

るるとん@Kさんありがとうございます。
早速頂いたコードを打ってやってみましたが何も現われない?(笑わないで下さい)  なおエラーが出ましたのでcreate(Self)にしたら直りました。しかし任意にソフト上でコンポーネント配列が作れることとが分かりましたのでこれから「create」なるキーワード、Parentなどのヒントを頂戴しましたのでこれらを足がかりに何とかモノにしていきたいと思います。当方の悩みは参考書などがないこと、HELPでのサンプルコードが乏しい(あるのかもしれませんが知らない)ことなどで進歩がないのが実情です。  皆様はどのように学習されたのでしょうか?  参考書などその手がかりをご披露ください。


take  2004-08-04 01:45:25  No: 10209

残念ながらVBのようなコントロール配列はありません。
デザインしにくくはなりますが自身で作成し管理する方法を説明します。
(座標管理だけを行うなら別の方法のほうが良いかもしれません)

Form1のイベント
OnCreateをダブルクリックしてイベントを作り
その中にコードを書きます。

procedure TForm1.FormCreate(Sender: TObject);
var
  i : Integer;
  d : TLabel;
begin
  for i := 0 to 9 do begin
    d := TLabel.Create(Self);  // ラベルコンポーネントを生成
    d.Parent := Form1;         // 土台にするコンポーネントを指定
    d.Left := 50;              // X座標を指定
    d.Top := i * 20;           // Y座標を指定
    d.Caption := IntToStr(i+1)+'番目のラベル';  // 表示内容
  end;

end;

あと一番上の usesにStdCtrlsを追加する必要があります。

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;// <- こんな感じ

作ったコンポーネントは自分で破棄してやらないと本当は駄目ですが
Create(Self)の働きで自動で破棄してくれます。

で話は変わりますけど、るるとん@Kさんは前に
「今後PDAからは投稿しません」
「動作検証していないソースは書きません」
と約束しませんでしたっけ?


take  2004-08-04 02:02:41  No: 10210

>参考書などその手がかりをご披露ください。
今回のようなコンポーネントの生成のとき役に立つ書籍は
「Delphiコンポーネントプログラミング」
になるかと思います。(古い書籍ですが)
この辺がわかってくるとDelphiでのプログラム開発が楽しくなりますよ


jok  2004-08-04 07:40:15  No: 10211

> 皆様はどのように学習されたのでしょうか?

今回の質問に限れば、たんにクラスとそのインスタンスの生成法の一般論にすぎ
ません。コンポーネントは TComponent クラスの派生クラスであり、コンポーネ
ントパレットに載せることが出来るだけが特別なのであり、クラスであることに
はかわりありません。コンストラクタを使ってインスタンスをつくるだけです。
コードで破棄するときは Free メソッドを使います。コンストラクタで Owner
を設定した場合は、終了時に自動的に破棄されます。

クラスについては一言で説明できないのですが、入門サイトで一通り Delphi に
ついて学ぶと、コードでインスタンスをつくるのは、非常に簡単であり、Tips に
さえならない問題であることが理解できるようになります。

入門サイトとして

http://kakinotane.s7.xrea.com/

の Delphi入門 をおすすめしておきます。


初心者M  2004-08-04 20:45:35  No: 10212

皆様、大変貴重なアドバイスをありがとうございました。  jokさんご推奨の入門サイトを今一通りさっと見たところです。インスタンス?  コンポーネントパレット?  コンストラクタ?  聞きなれないものばかりで戸惑いますがDelphiをやるにはこれらの言葉を確実に理解していないと先に進めそうにないと観念しました。  VBではこのような概念を正確に知らなくてもN88Basic流にサンプルコードや「技シリーズ」などを参考にゴリゴリと大体のことはやってきましたがDelphiではこれらの用語の正確で、しかも実際に活用できる知識が必要であることを痛感しました。  

安易にも「こうやって打ちこめば出来ちゃうよ」みたいなことを期待していましたがそうも行きそうにないことがわかりました。  しかし身近には教えてくれる人もないアマチュアなのでやはり具体的にコードを打ちこんで動かしてみて、後になって「これが所謂**だったのか」ということで覚えて行くしかなさそうです。ご推奨の入門サイトはお気に入りに入れました。勉強します。  ありがとうございました。


初心者M  2004-08-04 21:40:13  No: 10213

すみません。  質問が出てしまいましたので解決の取り消しです。

実はtakeさんからいただいた極めて具体的なサンプルコードをやっていたのですが私の初歩的なミスがあってどうしてもうまくいかなくて落ち込んでいました。しかしミスを発見して正常に動作しました。  ありがとうございます。  これで具体的に開発が進みそうで今は鬱から爽に急変しました。

そこで超初心者レベルの質問で申し訳ありませんがもう一つ教えてください。
①  例えばLabelの3番目のCaptionを後で変えようとしたらどのようにするのでしょうか?  (VBでしたら  Label1(3).caption=”BBBBB"みたいにしたい)
②  これと同じやりかたでEdit、PaintBoxなども随時増減できるのでしょうか?

宜しくお願いします。


bob  2004-08-04 22:40:40  No: 10214

takeさんのコードに動的配列を付け加えました。

procedure TForm1.FormCreate(Sender: TObject);
var
  i : Integer;
  d : array[0..9] of TLabel;
begin
  for i := 0 to 9 do begin
    d[i] := TLabel.Create(Self);  // ラベルコンポーネントを生成
    d[i].Parent := Form1;         // 土台にするコンポーネントを指定
    d[i].Left := 50;              // X座標を指定
    d[i].Top := i * 20;           // Y座標を指定
    d[i].Caption := IntToStr(i+1)+'番目のラベル';  // 表示内容
  end;

end;


bob  2004-08-04 22:41:12  No: 10215

うそ。静的配列ですな。


bob  2004-08-04 22:49:37  No: 10216

さらにレス
> ②  これと同じやりかたでEdit、PaintBoxなども随時増減できるのでしょうか?
→できます。
 TEditやTPaintBoxをCreateすればできます。

また変数としてよく使うTStringList等も同様です。
ただし、TStringList等はJokさんが仰ってるとおり、TComponentの派生クラス
ではないので、Freeで解放する必要があります。
#VB.NETも同様

procedure TForm1.FormCreate(Sender: TObject);
Var
  StrList: TStringList;
begin
  StrList := TStringList.Create;
  try
    StrList.Add('aiueo');
    StrList.Add('abcdef');
    Form1.Caption := StrList.Text;
  finally
    StrList.Free;
  end;
end;


bob  2004-08-04 23:11:03  No: 10217

誤爆した以上、動的につくるには?  って質問が出そうだから、先回り
Formにボタンを1つ貼り付けてください。

  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    FList: TList;
  public
    { Public 宣言 }
  end;

(略)
procedure TForm1.FormCreate(Sender: TObject);
begin
  FList := TList.Create;        // 動的生成の変数
end;

procedure TForm1.Button1Click(Sender: TObject);
Var
  I: Integer;
  tmpEdit: TEdit;
begin
  if FList = nil then
    FList.Clear;

  i := FList.Count;
  tmpEdit := TEdit.Create(nil); // Editコンポーネントを生成(nilで生成)
  with tmpEdit do               // VBにもありますな。
  begin
    Parent := Form1;
    Left := 50;
    Top := i * 20;
    Text := Format('%d番目のラベル', [i]);  // VBにもありますな。
  end;

  FList.Add(tmpEdit);           // 動的にEEditコンポーネントを追加

end;

procedure TForm1.FormDestroy(Sender: TObject);
Var
  I: Integer;
begin
  for i:=0 to FList.Count -1 do
    TEdit(FList.Items[i]).Free; // 動的に(Button1で)生成したのを解放

  FList.Free;
end;


bob  2004-08-04 23:48:13  No: 10218

間違えてる。鬱。

  if FList = nil then
    FList.Clear;
        ↓
  if FList = nil then
    FList.Create;


初心者M  2004-08-05 01:34:26  No: 10219

bobさん、早速の具体的なコンポーネント配列の例をありがとうございました。  bobさんの一番最初のレスは私の(怪しげな)理解の範囲内ですので早速イタダキました。  しかし後編の動的配列???などに関しては今は最初に頂いたコードを理解するのに頭が満杯ですのでレベルが上がって分かってくるまではお預けです。

これだけのコードを短時間で書き上げるのには感心しました。  最後に毎度素朴な質問で申し訳ありませんが  ①コードが大文字、小文字になっていますが(私の場合は)変数を宣言してもコードが小文字のままです。  VBのように宣言した変数、予約語を自動的に大文字小文字にする方法はあるのでしょうか?  コードを打ちこんでいても間違っているのではないかと気になります。


take  2004-08-05 01:50:52  No: 10220

残念ながら自動的には変換されませんし後から変換する便利な方法も存在しません
VBの頃は便利な機能だと思っていましたがかえって邪魔なこともありますよ
ただ入力中にCtrl + スペースキーで入力補助してくれる機能がありますから
それで大文字小文字の関係が崩れないように心がけています。
FList.Free;を入力するとき

Fを入力後Ctrl + スペースキー、一覧からFListを選択
.を入力、補完機能が自動的に働くのでFを押してFreeの近くまでカーソルを
持ってきてFreeを選択。自分で打つほうが早いかもしれませんが
こんな方法で入力しています。

for文とかはforを入力してからCtrl+Jで自動的に色々手助けしてくれると思います。

もしかしてパーソナル版で勉強しているのでしょうか?
パーソナル版ではなかったかもしれません。


bob  2004-08-05 02:11:17  No: 10221

Pascal系言語はBASIC系と同じで、C系やJavaとは違い大文字/小文字は
区別しませんので同じ物として扱います。VBも区別しません。

VBで自動的に大文字/小文字に変換してくれるのは、IDEのエディタが
やってくれているのです。(VBがインタプリタだからやりやすい?)

結論ですが"標準ではできない"です。
技術的にはたぶん出来ると思うので、探せばあるのではないでしょうか?
#僕は探したこと無いので、わかりません。

P.S.
このスレッドはもう"解決"になっているので、質問を出す場合は
新しいスレッドを建てた方がいいですよ。


初心者M  2004-08-05 19:36:05  No: 10222

皆様、短期間に実に色々なことをご指導いただきやっとコードを打ちこんで試せるという取っ掛かりができました。  N88かなVBに移行の時は本を見て悶々としてかなりの時間(1年以上?)を費やしましたが実際に打ちこんでみてその動き、やりかたが分かってきてN88流VBで何とか思ったことができるようになりました。おかげでDelphiではこの最初の悶々から極めて短時間に脱却できるのではないかと希望が持てそうです。  感謝あるのみです。  またお願いします。

ついつい同じスレッドで違う質問をしてしまい失礼しました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加