複数のFormを追加したい

解決


勉強中  2007-10-06 04:22:27  No: 27963

Formを追加する方法が分からず一つのFormでばかり作ってきましたがどうしても複数のFormが必要になりました。仕様としては  起動するとForm1を表示、ボタンでForm2またはForm3を表示しボタンにより自由に複数のFormを切り替えるというものにしたいと考えています。その場合変数のスコープを複数のFormに有効にする書き方などもわかりません。数冊の入門書、WEBサイトを見た限りでは複数のフォームの事が見つかりませんのでよろしくお願いします。


これは?  2007-10-06 16:29:49  No: 27964

http://www.knet.ne.jp/~touka/other/delphi.html


HOta  2007-10-06 18:17:22  No: 27965

最初に表示するForm以外は、自動生成から外しておきましょう。


こんなこと?  2007-10-06 18:53:59  No: 27966

フォームを動的に作成したいって事なのかな?

var
  Form2 : TForm;
begin
  Form2 := TForm2.Create(Self);
  if Form2.ShowModal = mrOk then 
  begin

  end;
  Form2.Release;
end;


勉強中  2007-10-07 04:18:35  No: 27967

皆様、色々とありがとうございます。これは?様ご紹介のサイトで複数のFormを「ファイル」「新規作成」から作成することを知り、作るところまではできました。(VBの経験からプロジェクトから作るはずと思っていました)

希望する仕様は
1.VBのSub Main()でやるように最初に表示するFormを指定したい。
2.これら複数のFormをボタン操作などで渡り歩くようにしたい。(例えばVBでForm2.Showとやるように)
3.その際表示されないFormはCloseさせたい。(HOta様の言っておられることと同じかと思います。但しそれぞれのFormはパネルやボタンなどを設計時に配置だけはしておきたい。詳細位置は表示の際に指定)
4.複数のFormに共通の変数(Global/Public)を持ちたい。

本当に初歩的で申し訳ありませんが独学ゆえに実例を見る機会もありませんのでよろしくお願いします。


HOta  2007-10-07 05:37:12  No: 27968

http://www2.big.or.jp/~osamu/Delphi/tips.cgi?index=0295.txt
の事でしょうか?

判らなければ、例を示して質問した方が、レスポンスがつきやすいですよ。


これは?(2)  2007-10-07 05:40:38  No: 27969

フォームを新規作成で追加できたようですね。
とりあえず、新規プロジェクト(フォームはForm1のみ存在)で、Form2を
新規追加した状態でどのようにするかを大まかに書いてみたいと思います。

①unit1 のuses に、unit2 が追加されていることを確認する。
②unit1 の
      var
        Form1: TForm1;
  の下に、
        Form2: TForm2;
  を追加する。
③IDEのメインメニューのプロジェクト−オプションのフォーム
  タブから、Form2を自動生成対象ウィンドウからはずす。
  (選択可能なフォームに持ってくる。)
  もしメインフォームを変えたければ、同じくここで変更する。
  ※いらないフォームは最初はロードせず、必要なところで
    動的生成して対応するための前準備。
④あとは、こんなこと?さんが書いているような処理を書く。

begin
  Form2 := TForm2.Create(Self);
  Form2.ShowModal; //モーダルなウィンドウを表示。
  Form2.Release; //ウィンドウを閉じた後は、ウィンドウが不要になるので開放。
end;

もしモーダルでないウィンドウを扱うのであれば、下のような感じになると思います。

begin
  Form2 := TForm2.Create(Self);
  Form2.Show;
  //Form2.Release; //これは不要。ですがForm2のOnCloseイベントに
  //Action := caFree; を記述して、閉じたときにウィンドウが開放
  //されるようにおいてください。
end;

複数のフォームに共通の変数を持ちたいということですが、例えばForm1
のpublicあたりに変数を宣言してはどうですか?
Unit2からも、Form1.hoge とか書けばアクセスできますよ。


勉強中  2007-10-08 03:08:08  No: 27970

HOta様、これは?(2)様、ご指導をありがとうございます。解決サインを出そうと朝から簡単なことを何度も何度も繰り返していますがForm2からForm1を呼び出すところまで行き着きませんので再度ご指導をお願いします。

仕様は:①Form1にボタン1を配置してボタンを押すとForm2がモーダルで表示される。②Form2にボタン1、ボタン2、Edit1を配置してボタン1を押すとEdit1にパブリック宣言した(つもりの)A+Bを表示し、③ボタン2を押すとForm1へ戻る。というものをテストしたいと試験しました。(下記)

結果は①だけまではOK  ②は未定義の識別子'A'と出てしまう。  ③はForm1.Show; などと書くとUsesリストにない、という警告が出ます。そこでUnit2のUsesにUnit1と書くと循環参照と出てしまいます。

単純にするためにモードレスでもOKと試しましたが基本的なことが分かっていませんのでうまくいきませんでした。このあたりの処理などお教えください。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Unit2, StdCtrls;  //  Unit2は自動生成されませんので手書きで加えました

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }

    A,B,C,D:real;
  end;

var
  Form1: TForm1;
  Form2: TForm2;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2 := TForm2.Create(Self);
  Form2.ShowModal;   Form2.Release; 
end;
end.

----------------------------------------------------
unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form2: TForm2;

  implementation

{$R *.dfm}

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
 // edit1.text:=floattostr(A+B);
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
//Form1.show; (モードレスにすればOKかと思いましたがForm1のことを書くと全て拒絶されてしまいます。)
end;

end.


その3  2007-10-08 05:41:57  No: 27971

Unit2 の

implementation

の下の行に、

uses Unit1;

を追加してみてください。(Delphi6では自動で追加されてました。)

それで、unit2からは、変数へのアクセスはForm1.Aなどと書きます。
単なるAでは不可です。


老婆心  2007-10-08 07:37:35  No: 27972

Unit1、Unit2の両方のユニットの中で、
この↓同じ変数Form2を定義するのは、やめたほうがいいよ。
Form2: TForm2;

両方のユニットの中のForm2は別の変数と解釈されるので、
重複定義エラーにはならずに、思わぬバグの元なることもあり、
どちらかひとつだけに(Unit1内のForm2変数は削除)するべき。


HOta  2007-10-08 16:34:22  No: 27973

丸数字はやめましょう。
1,2は他の方が答えてくれていますので、
3の問題ですが、変数の型・スコープをもう少し詳しく勉強してください。
Form2から、Form1を呼び出しているのですが、
Form1の宣言がForm2のどこにも無いのでエラーになっています。
また、ShowModalでForm2を表示していますの、Form2は自分で消すだけです。
Form1はForm2の下側に表示されています。(操作はできませんが)
ですから、ここでは、Form2.Close;とします。


勉強中  2007-10-08 19:52:30  No: 27974

皆様、とうとうできました。各位のご親切に心よりお礼申し上げます。関連して変数のスコープなどもいろいろいじったおかげですこしづつ分かったように思います。

ここで単に解決のサインを書いてもライブラリになりませんのでサーバー容量を喰って申し訳ありませんが全プロセスを書かせていただきます。

(A)Formの配置
1.(現在Form1がある状態で)ファイル→新規作成→フォーム  でForm2を追加
2.Form2.Visible:= False;であることを確認(最初からFalseになっていました)
3.プロジェクト→オプション→フォームでForm2を自動生成から外す
4.Form1.For2にボタン、Editなどのコンポーネントを配置

(コード):下記のようになりました。(何か怪しい点がありましたらご指摘ください)

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
    A,B,C:real;
  end;

var
  Form1: TForm1;
 // Form2: TForm2;   これがあるとUnit2のButton2をクリックすると「読み込み違反」のメッセージが出ましたが老婆心さまのご指摘の通り消したらエラーをパスできました。

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
a:=5;  b:=6;  c:=7;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form1.visible:=false;
  Form2 := TForm2.Create(Self);
  Form2.ShowModal; //モーダルなウィンドウを表示。
  Form2.Release; //ウィンドウを閉じた後は、ウィンドウが不要になるので開放。
end;

end.

----------------------------------------------------
unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form2: TForm2;
  A,B,C:real;

implementation
  uses Unit1;  //D6パーソナルでは自動で追加されませんでしたので手動で追加

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
a:=form1.A;
b:=form1.B;
c:=form1.C;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
edit1.Text:=floattostr(a+b+c);
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
form1.visible:=true;
form2.Close;
end;

end.

ありがとうございました。


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

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






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