Formを追加する方法が分からず一つのFormでばかり作ってきましたがどうしても複数のFormが必要になりました。仕様としては 起動するとForm1を表示、ボタンでForm2またはForm3を表示しボタンにより自由に複数のFormを切り替えるというものにしたいと考えています。その場合変数のスコープを複数のFormに有効にする書き方などもわかりません。数冊の入門書、WEBサイトを見た限りでは複数のフォームの事が見つかりませんのでよろしくお願いします。
http://www.knet.ne.jp/~touka/other/delphi.html
最初に表示するForm以外は、自動生成から外しておきましょう。
フォームを動的に作成したいって事なのかな?
var
Form2 : TForm;
begin
Form2 := TForm2.Create(Self);
if Form2.ShowModal = mrOk then
begin
end;
Form2.Release;
end;
皆様、色々とありがとうございます。これは?様ご紹介のサイトで複数のFormを「ファイル」「新規作成」から作成することを知り、作るところまではできました。(VBの経験からプロジェクトから作るはずと思っていました)
希望する仕様は
1.VBのSub Main()でやるように最初に表示するFormを指定したい。
2.これら複数のFormをボタン操作などで渡り歩くようにしたい。(例えばVBでForm2.Showとやるように)
3.その際表示されないFormはCloseさせたい。(HOta様の言っておられることと同じかと思います。但しそれぞれのFormはパネルやボタンなどを設計時に配置だけはしておきたい。詳細位置は表示の際に指定)
4.複数のFormに共通の変数(Global/Public)を持ちたい。
本当に初歩的で申し訳ありませんが独学ゆえに実例を見る機会もありませんのでよろしくお願いします。
http://www2.big.or.jp/~osamu/Delphi/tips.cgi?index=0295.txt
の事でしょうか?
判らなければ、例を示して質問した方が、レスポンスがつきやすいですよ。
フォームを新規作成で追加できたようですね。
とりあえず、新規プロジェクト(フォームは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 とか書けばアクセスできますよ。
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.
Unit2 の
implementation
の下の行に、
uses Unit1;
を追加してみてください。(Delphi6では自動で追加されてました。)
それで、unit2からは、変数へのアクセスはForm1.Aなどと書きます。
単なるAでは不可です。
Unit1、Unit2の両方のユニットの中で、
この↓同じ変数Form2を定義するのは、やめたほうがいいよ。
Form2: TForm2;
両方のユニットの中のForm2は別の変数と解釈されるので、
重複定義エラーにはならずに、思わぬバグの元なることもあり、
どちらかひとつだけに(Unit1内のForm2変数は削除)するべき。
丸数字はやめましょう。
1,2は他の方が答えてくれていますので、
3の問題ですが、変数の型・スコープをもう少し詳しく勉強してください。
Form2から、Form1を呼び出しているのですが、
Form1の宣言がForm2のどこにも無いのでエラーになっています。
また、ShowModalでForm2を表示していますの、Form2は自分で消すだけです。
Form1はForm2の下側に表示されています。(操作はできませんが)
ですから、ここでは、Form2.Close;とします。
皆様、とうとうできました。各位のご親切に心よりお礼申し上げます。関連して変数のスコープなどもいろいろいじったおかげですこしづつ分かったように思います。
ここで単に解決のサインを書いてもライブラリになりませんのでサーバー容量を喰って申し訳ありませんが全プロセスを書かせていただきます。
(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.
ありがとうございました。
ツイート | ![]() |