[Delphi:91228] 条件下での変数宣言

101 views
Skip to first unread message

松本 英俊

unread,
Mar 24, 2009, 10:26:13 PM3/24/09
to Del...@ml.users.gr.jp
松本です

ある条件下で、変数の宣言をしたいのですがどうすれば良いでしょうか
たとえば
procedure UsesForm(FormNo:Integer)
if FormNo =1 then begin
var TempForm:TForm1;
TempForm:=TForm1.Create(Self);
end;
if FormNo =2 then begin
var TempForm:TForm2;
TempForm:=TForm2.Create(Self);
end;
begin

以後、TempFormを使用する

end;
こんなことは、出来ませんか
$IFコンパイラ指令なんかで、出来ないかともだえていましたが
どうにも解決しませんでした

Del 2007
WinXp

よろしくお願いします

as...@sickroom.104.net

unread,
Mar 24, 2009, 10:44:51 PM3/24/09
to Del...@ml.users.gr.jp
 細川です。

  変数を宣言するというわけではないのですが、松本さんのやりたい事はメタ
クラスを使えばできると思います。
 ↓こんな感じでいかがでしょう?(検証はしていません)

type
TFormClass = class of TForm;

procedure UsesForm(FormNo: Integer);
var
TempFormClass: TFormClass;
TempForm: TForm;
begin
if (FormNo = 1) then
TempFormClass = TForm1;

if (FormNo = 2) then
TempFormClass = TForm2;

TempForm = TempFormClass.Create(Self);


end;

On Wed, 25 Mar 2009 11:26:13 +0900
松本 英俊 <hidetoshi...@highway-kansei.co.jp> wrote:

> procedure UsesForm(FormNo:Integer)
> if FormNo =1 then begin
> var TempForm:TForm1;
> TempForm:=TForm1.Create(Self);
> end;
> if FormNo =2 then begin
> var TempForm:TForm2;
> TempForm:=TForm2.Create(Self);
> end;
> begin


Regards,
HOSOKAWA Jun
[S/G] SERIALGAMES Inc.
TEL: 03-5812-0980
FAX: 03-5812-0970
mailto: j...@serialgames.co.jp
fla:ver http://flaver.jp/
tokotto http://www.serialgames.co.jp/tokotto/
WebCapS http://www.serialgames.co.jp/fun.html#WebCapSeria


Masayuki Yoneda

unread,
Mar 24, 2009, 10:47:39 PM3/24/09
to Del...@ml.users.gr.jp
米田と申します。

TempFormはTForm型として、クラス参照型などを使えば問題ないのではないでしょうか

procedure UsesForm(FormNo:Integer)


type
TFormClass = class of TForm;

const
FORM_COUNT = 2;
FORM_TBL: array [1..FORM_COUNT] of TFormClass = (
TForm1,
TForm2
);
var
TempForm: TForm;
begin
if FormNo in [1..FORM_COUNT] then
TempForm := FORM_TBL[FormNo].Create({オーナー});
else
Exit;
{ 以降、(TempForm as FORM_TBL[FormNo])として使う }
end;

こうすればFORM_TBLの配列数を増やせばいろんな種類のフォームを使えますよ。


--
HTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHT

MCU応用技術部 T2グループ
米田 真之(Yoneda Masayuki)

Mail : yoneda....@sunnygiken.co.jp

HTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHT

高木太郎

unread,
Mar 24, 2009, 10:52:49 PM3/24/09
to Del...@ml.users.gr.jp
 こんにちは、イマジオムの高木です。

松本さん:


> procedure UsesForm(FormNo:Integer)
> if FormNo =1 then begin
> var TempForm:TForm1;
> TempForm:=TForm1.Create(Self);
> end;
> if FormNo =2 then begin
> var TempForm:TForm2;
> TempForm:=TForm2.Create(Self);
> end;
> begin
>
> 以後、TempFormを使用する
>
> end;
> こんなことは、出来ませんか

 次のようにすればできます。

type TForm1=class(TForm)

end;

type TForm2=class(TForm)

end;

procedure UsesForm(FormNo:Integer);

var TempForm:TForm;

begin
if FormNo=1 then TempForm:=TForm1.Create(Self) else
if FormNo=2 then TempForm:=TForm2.Create(Self) else
Exit;

//以後、TempForm を使用する。たとえば……
TempForm.ShowModal;

TempForm.Free;
end;
――――――――――――――――――――――――――――――――――――
株式会社イマジオム 代表取締役 高木太郎
〒316-0024 茨城県 日立市 水木町 1-11-10
電話:0294-28-0147
ファクシミリ:0294-28-0148
電子メール:tarou_...@imageom.co.jp
ホームページ:http://www.imageom.co.jp/

as...@sickroom.104.net

unread,
Mar 24, 2009, 11:01:10 PM3/24/09
to Del...@ml.users.gr.jp
 細川です。

 なぜかメタクラスで考えてしまいましたが、その通りですね。
 単に TempForm を親クラスの TForm や TCustomForm なんかにすればいいだけ
ですね。

松本 英俊

unread,
Mar 24, 2009, 11:32:36 PM3/24/09
to Del...@ml.users.gr.jp
松本です 
皆さんありがとうございます
早速、試してみます

Mr. Kazutaka Morono

unread,
Mar 24, 2009, 11:37:09 PM3/24/09
to Del...@ml.users.gr.jp
諸農です。

松本 英俊 <hidetoshi...@highway-kansei.co.jp>さん:


FormNoで分岐するなら、TempFormはTForm型で宣言すれば良いような気もします。

もしくは、TFormBaseか何かでvirtualメソッドを準備しておいて、継承したTForm1と
TForm2でメソッドをそれぞれの実装でオーバーライドすればFormNoで分岐しなくても
しのげるかもしれません。


■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■
◇ 諸農和岳 <k-mo...@mbm.nifty.com>
■ Kazutaka Morono - Osaka , Japan

■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■◇■

高木太郎

unread,
Mar 24, 2009, 11:45:44 PM3/24/09
to Del...@ml.users.gr.jp
 こんにちは、イマジオムの高木です。

細川さん:


>  なぜかメタクラスで考えてしまいましたが、その通りですね。
>  単に TempForm を親クラスの TForm や TCustomForm なんかにすれば
> いいだけですね。

 ええ、ただ実際の実装では、おっしゃるようにメタ(上位)クラス型を
使うことが多いですよね。

 今後のアプリケーションの拡張を考えると、GUIというのは一番変わる
可能性が高いわけですから、どうしても新しいフォームが追加されることを
想定しなければなりません。 そこで私は、それぞれのフォームの外観や
挙動を揃えるために、いったん共通の性質(たとえば、被所有フォームに
する、OKボタンとキャンセルボタンを持つ、特定の条件でモーダル表示を
打ち切る、など)を持つ上位フォームクラスを定義し、以後はその抽象的な
フォームに対して処理を行うような実装にするように、心がけています。
こうすると、フォームの種類に変更があっても、修正が最小限ですみます。

 たとえば次のようです。


// 抽象的なフォームのクラスを定義。
type TAppForm=class(TForm)
constructor Create(AOwner:TComponent;
OwnerForm:TForm); reintroduce;
public
OKButton :TButton;
CancelButton:TButton;
procedure OKButtonClick(Sender:TObject); virtual;
procedure BreakModal;
end;

// 具体的なフォームのクラスを、上記のサブクラスとして定義。
type TForm1=class(TAppForm)
UserNameEdit:TEdit;
PasswordEdit:TEdit;
end;

type TForm2=class(TAppForm)
HostEdit:TEdit;
PortEdit:TEdit;
end;


type TAppFormClass=class of TAppForm;

var FormClass:TAppFormClass;
Form:TAppForm;

begin

// FormNumber によって表示されるフォームが変わる。
case FormNumber of
1:FormClass:=TForm1;
2:FormClass:=TForm2;
end;

// いったんクラスを選ぶと、以後は TForm1 や TForm2 に依存しない
// 実装ができる。 ∴フォームの種類が増えても修正しなくてよい。
Form:=FormClass.Create(nil,Self);
Result:=Form.ShowModal;

松本 英俊

unread,
Mar 25, 2009, 12:08:36 AM3/25/09
to Del...@ml.users.gr.jp

松本です
試しました
Form1,Form2,Form3を作成し
Form1とForm2を使用可能フォームとして

procedure TForm3.Button1Click(Sender: TObject);
begin
UsesForm(2);
end;

procedure TForm3.UsesForm(FormNo:Integer);


var
TempForm:TForm;
begin
if FormNo=1 then TempForm:=TForm1.Create(Self) else

if FormNo=2 then TempForm:=TForm2.Create(Self) ;
TempForm.ShowModal;
end;
Form2に何も無い場合はForm2が表示されましたが
Form2にEditを貼り付けると
クラス Editが見つかりません とエラーが出ます
なぜなのか解りません

松本 英俊

unread,
Mar 25, 2009, 12:22:38 AM3/25/09
to Del...@ml.users.gr.jp
松本です
米田さんありがとうございます
implementation

{$R *.dfm}


procedure UsesForm(FormNo:Integer);
type
TFormClass = class of TForm;
const
FORM_COUNT = 2;
FORM_TBL: array [1..FORM_COUNT] of TFormClass = (
TForm1,
TForm2
);
var
TempForm: TForm;
begin
if FormNo in [1..FORM_COUNT] then

TempForm := FORM_TBL[FormNo].Create(application)


else
Exit;
{ 以降、(TempForm as FORM_TBL[FormNo])として使う }

(TempForm as FORM_TBL[FormNo]).Show;
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
UsesForm(2);
end;

Form2が空の場合はForm2は表示されますがEdit等をForm2の貼り付けると
エラーが出ます

Masayuki Yoneda

unread,
Mar 25, 2009, 12:33:36 AM3/25/09
to Del...@ml.users.gr.jp
米田です。

恐らくTempForm.Editとしている為Editが見つからないのだと思いますので
助言を。

TempFormの型はTFormなんで当然Editは含まれていません。

なので型を判断し、キャストしてやる必要があります。

if FormNo = 2 then
begin
(TempForm as TForm2).Edit.Text := 'ボタン';
end;

Componentsプロパティを使うという荒技も出来なくはないですが・・・

以上、ご確認よろしくお願いします。

松本 英俊

unread,
Mar 25, 2009, 12:34:21 AM3/25/09
to Del...@ml.users.gr.jp
松本です
すみません
出来ました
ありがとうございました

Mr. Kazutaka Morono

unread,
Mar 25, 2009, 1:38:52 AM3/25/09
to Del...@ml.users.gr.jp
諸農です。

松本 英俊 <hidetoshi...@highway-kansei.co.jp>さん:


> Form2にEditを貼り付けると
> クラス Editが見つかりません とエラーが出ます
> なぜなのか解りません

それは、もしかすると

TempForm.Edit1.Text := 'HogeHoge';

みたいなことをしようとしたら、の意味ですか?

TempFormの型であるTForm型にEdit1は定義されていないからですね。

TForm1とTForm2のインスタンスの使い方を整理した上で、基底クラスを設計した方が
良いと思います。

例えば基底クラスに
SetEditText(str:string);virtual;abstract;
なんてメソッドを作っておくとか、プロパティを作っておくとかで、
TForm1でのSetEditTextの実装は何もせずに(一応override宣言しておきます)、
TForm2での実装はフォームに貼り付けたEdit1のTextプロパティを操作するとか。

取り出しも同じで
GetEditText:string;virtual;abstract;
みたいな感じでやれば良いんじゃないでしょうか。

Reply all
Reply to author
Forward
0 new messages