処理を共通化するには?

解決


茶色  2007-02-09 04:39:40  No: 24831

MDIForm内に複数のFormがあって(Form2/Form3/Form4・・・)、これを一つの処理で操作したい場合、

  // Form2が選択された
  if Index = 0 then begin
    Form2.Label1.Caption := 'Hello World';

  // Form3が選択された
  end else if Index = 1 then begin
    Form3.Label1.Caption := 'Hello World';

  // Form4が選択された
  end else if Index = 2 then begin
    Form4.Label1.Caption := 'Hello World';
  end;

の様に、条件文で処理を分岐させる以外でスマートなやり方はないでしょうか?


HOta  2007-02-09 04:46:14  No: 24832

Case文です。

Case Index of
0:
    Form2.Label1.Caption := 'Hello World';
1:
    Form3.Label1.Caption := 'Hello World';
2:
    Form4.Label1.Caption := 'Hello World';
end;


茶色  2007-02-09 05:11:48  No: 24833

HOtaさん
回答有難う御座います。

こちらの説明不足だったかもしれませんが、If文やCase文を使わずに出来ないか?  と言うのを目的としてますので、せっかく教えて頂いたのですが、これだと・・・。

理想としてはこんな感じにならないかなぁと考えております。
// Form2が選択された
if Index = 0 then begin
Form := Form2;

// Form3が選択された
end else if Index = 1 then begin
Form := Form3;

// Form4が選択された
end else if Index = 2 then begin
Form := Form4;
end;

Form.Label1.Caption := 'Hello World';

以降この処理を抜けるまで「Form」で操作できる。


みんみん  2007-02-09 06:29:37  No: 24834

数値から処理対象のTFormを取得したいわけですね。
FindComponent試してみてください。
TFormのnameがForm1,Form2,Form3..となっていることが前提ですが...。

var
 frm :TForm;
begin
 //質問では index=0 で Form2の処理のようなので
 frm :=TForm(FindComponent('Form'+InttoStr(index+2)));
  with frm do begin
    Label1.Caption :='Hello World';
    
    //以下目的の処理を記述
  
  end; //with
end;


田中  2007-02-09 08:33:22  No: 24835

複数のオブジェクトを管理するなら、こんな方法もあります

procedure TForm1.Button1Click(Sender: TObject);
var
  obj  : TObjectList;
  Index: Integer;
begin
  Index := 0;
  obj := TObjectList.Create(True);
  obj.Add(TForm2.Create(Application));
  obj.Add(TForm3.Create(Application));
  obj.Add(TForm4.Create(Application));
  (obj.Items[Index] as TForm).Caption := 'Hello World';
end;


茶色  2007-02-09 19:00:57  No: 24836

みんみんさん
田中さん
回答有難う御座います。

早速試して見たのですが、どちらの場合でも各Formに貼り付けられた
コンポーネントへの処理部分でコンパイルエラーになってしまいます。
(それ以前に貼り付けたコンポーネントがリストに出て来ない)

勉強不足でスミマセンが、上記の方法で、各Formに貼り付けられた
コンポーネントへアクセスする方法は有りますでしょうか?


にしの  2007-02-09 19:28:12  No: 24837

Formに貼り付けられたコンポーネントも、FindComponentで探せばよいかと。
みんみんさんのコードで言うならば、

var
 frm :TForm;
begin
 //質問では index=0 で Form2の処理のようなので
 frm :=TForm(FindComponent('Form'+InttoStr(index+2)));
  with frm do begin
    TLabel(FindComponent('Label1')).Caption :='Hello World';  
  end; //with
end;

こんな感じで。
# 未検証です


えーと  2007-02-09 19:35:30  No: 24838

MDI子フォームでも現在アクティブなフォームは Screen.ActiveForm でわかりますよ。

こんな感じ。

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
  public
    procedure ActiveFormChange(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ActiveFormChange(Sender: TObject);
var
  ActiveForm: TForm;
begin
  ActiveForm := Screen.ActiveForm;
  Caption := ActiveForm.Caption
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Screen.OnActiveFormChange := ActiveFormChange;
end;

詳しくはヘルプで。


えーと  2007-02-09 19:49:31  No: 24839

あ、それから普通の TForm には Label1 というようなフィールドはありませんので、
実際の子フォームの型にキャストしてからアクセスする必要があります。


茶色  2007-02-10 00:26:54  No: 24840

にしのさん
えーとさん
回答有難う御座います。

にしのさん
コンパイルエラーにはならなくなったのですが、実行するとエラーになります。
どうにかならないか、もう少し考えてみたいと思います。

えーとさん
(Screen.ActiveForm as TForm2).Label1.Caption := 'Hello World';
上の様にキャストして、Form2をアクティブにした状態で行うと上手く行くのですが、これだとキャスト時に使用するFormを指定する必要があるので、今回の目的にはちょっと適していない様です。

せっかく教えて頂いたのに、この様な物言いでスミマセン m(_ _ ")m


orz  2007-02-10 01:48:20  No: 24841

THogeForm=Class(TForm)
public
  Procedure SetLabel(aCaption: String); virtual; abstract;
end;

各フォームの継承元を TForm から THogeForm に変更
ソースコード上で、直接書き換え
TForm2=Class(THogeForm)
public
  Procedure SetLabel(aCaption: String); override;
end;

Procedure TForm2.SetLabel(aCaption: String);
begin
  //Form2では、TLabelに表示
  Label1.Caption := aCaption;
end;

TForm3=Class(THogeForm)
public
  Procedure SetLabel(aCaption: String); override;
end;

Procedure TForm3.SetLabel(aCaption: String);
begin
  //Form3では、TEditに表示
  Edit1.Text := aCaption;
end;

これでMDIChildがTHogeFormを継承したものであれば、いかの一行で済みます。
(Screen.ActiveForm as THogeForm).SetLabel('Hello World');

いかがかな?


えーと  2007-02-10 02:51:56  No: 24842

多態性を利用した処理の共通化をするには

1)下位クラスに型キャストをする。
2)上位クラスを共通化する。

これしかないですね。1)がいやなら orz さんのように2)にしなければなりません。


茶色  2007-02-10 02:59:14  No: 24843

orzさん
回答有難う御座います。

凄く参考になりました。
”新たなTFormクラスを作って、それを継承して各Formを作る。”
これを利用して、orzさんとはちょっと違ったアプローチでやってみようと思います。

↓他にもこう言う方法でやろうと考えていました。
procedure TForm1.LabelCaption(Index: Integer);
var
  lblCommon: TLabel;
begin
  if Index = 0 then begin
    lblCommon := Form2.Label1;
  end else begin Index = 1 then begin
    lblCommon := Form3.Label1;
  end;
  
  lblCommon.Caption := 'Hello World';
  // 以下、lblCommonで処理
end;
※↑単純にする為、Labelだけで考えています。


茶色  2007-02-10 02:59:56  No: 24844

えーとさん有難う御座います。


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

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






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