私はDelphi7を使用しており、プログラムでフォームを作成しようとしています。これが私のフォームクラススタブです:
unit clsTStudentInfoForm;
interface
uses Forms;
type
TStudentInfoForm = class (TForm)
end;
implementation
end.
メインフォームにもボタンがあり(これは、実行時に上記のフォームを作成して表示することになっている通常のフォームです)、クリックすると、学生フォームが作成されてモーダルウィンドウとして表示されます。フォームは表示されますが、何も表示されません。できることは、ウィンドウの右上隅にある閉じるボタンをクリックして閉じることだけです。
procedure TLibraryForm.btnShowStudentIfoFormClick(Sender: TObject);
var
f : TStudentInfoForm;
begin
f := TStudentInfoForm.CreateNew(Self);
f.ShowModal;
f.Free;
f := nil;
end;
プログラムで作成されたフォームにコンポーネントを追加する方法がわかりません(実行時ではなく、ソースコードに)。学生フォームに[OK]ボタンを追加し、キャプションとフォームの高さと幅を設定するコードを書くのを手伝ってもらえますか(コードは学生フォームファイルに記述する必要があります)。
任意の提案や例を高く評価します。ありがとうございました。
デフォルト(つまり、すべてのデフォルトIDE構成設定))では、新しく設計されたフォームが自動的に作成されます。メインフォームのみが表示され、セカンダリフォームは次のように表示できます。
_procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
Form3.ShowModal;
end;
_
この自動作成オプションを無効にすることをお勧めします。 [ツール]> [(環境)オプション]>(VCL)デザイナー> [モジュール作成オプション]に移動し、フォームとデータモジュールの自動作成オプションを無効/オフにします。
代わりに、必要な場合にのみ(すでに設計された)フォームを作成します。
_procedure TForm1.Button1Click(Sender: TObject);
var
Form: TForm2;
begin
Form := TForm2.Create(Self);
Form.Show;
end;
_
これは、セカンダリフォームのグローバル変数が不要であることも示しています。誤った使用を防ぐために、できるだけ早くそれらを削除することをお勧めします。
_type
TForm2 = class(TForm)
end;
//var
// Form2: TForm2; << Always delete these global variable
implementation
_
フォームデザイナでこのようなセカンダリフォームを設定したくない場合は、実行時にコードですべてのコントロールを作成する必要があります。次のように:
_unit Unit2;
interface
uses
Classes, Forms, StdCtrls;
type
TForm2 = class(TForm)
private
FButton: TButton;
public
constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
end;
implementation
{ TForm2 }
constructor TForm2.CreateNew(AOwner: TComponent; Dummy: Integer = 0);
begin
inherited CreateNew(AOwner);
FButton := TButton.Create(Self);
FButton.SetBounds(10, 10, 60, 24);
FButton.Caption := 'OK';
FButton.Parent := Self;
end;
end.
_
ご覧のとおり、私はCreateNew
コンストラクターを使用しました。これは 必要T(Custom)Form
導関数の場合:
CreateNew
の代わりにCreate
を使用して、関連する.DFMファイルを使用せずにフォームを初期化します。CreateNew
の子孫がTCustomForm
オブジェクトまたはTForm
の子孫でない場合は、常にTForm
を使用してください。
他のすべてのコンテナコントロール(TPanel
、TFrame
など)の場合、デフォルトのコンストラクターCreate
をオーバーライドできます。
このフォームを次のように呼び出します。
_procedure TForm1.Button1Click(Sender: TObject);
var
Form: TForm2;
begin
Form := TForm2.Create(nil);
try
Form.ShowModal;
finally
Form.Free;
end;
end;
_
または:
_procedure TForm1.Button1Click(Sender: TObject);
begin
FForm := TForm2.CreateNew(Application);
FForm.Show;
end;
_
この最後のケースでは、フォームは解放されませんが、閉じられると非表示になるため、その参照をプライベートフィールド(FForm
)に保存し、後で解放する必要があります。または、自動的に行うことができます。
_unit Unit2;
interface
uses
Classes, Forms, StdCtrls;
type
TForm2 = class(TForm)
private
FButton: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
public
constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
end;
implementation
{ TForm2 }
constructor TForm2.CreateNew(AOwner: TComponent; Dummy: Integer = 0);
begin
inherited CreateNew(AOwner);
OnClose := FormClose;
FButton := TButton.Create(Self);
FButton.SetBounds(10, 10, 60, 24);
FButton.Caption := 'OK';
FButton.Parent := Self;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
end.
_
これで、参照を保存せずに呼び出すことができます。
_procedure TForm1.Button1Click(Sender: TObject);
begin
TForm2.CreateNew(Self).Show;
end;
_
新しいフォームの所有者としてSelf
、Application
、またはnil
を渡すかどうかは、手動または経由で解放しない場合に、いつ自動的に破棄するかによって異なります。 OnClose
イベント。使用する
Self
:呼び出し元のフォームが破棄されると、新しいフォームが破棄されます。これは、呼び出しフォームがメインフォームではない場合に特に便利です。Application
:アプリケーションが終了すると、新しいフォームが破棄されます。これが私の好みの選択です。nil
:新しいフォームを破棄せず、アプリケーションの終了時にメモリリークが発生します。ただし、Windowsがプロセスを強制終了すると、メモリは最終的に解放されます。その場でコントロールを使用してモーダルフォームを作成するのは簡単です。
procedure CreateGreetingForm;
var
frm: TForm;
lbl: TLabel;
edt: TEdit;
btn: TButton;
begin
frm := TForm.Create(nil);
try
lbl := TLabel.Create(frm);
edt := TEdit.Create(frm);
btn := TButton.Create(frm);
frm.BorderStyle := bsDialog;
frm.Caption := 'Welcome';
frm.Width := 300;
frm.Position := poScreenCenter;
lbl.Parent := frm;
lbl.Top := 8;
lbl.Left := 8;
lbl.Caption := 'Please enter your name:';
edt.Parent := frm;
edt.Top := lbl.Top + lbl.Height + 8;
edt.Left := 8;
edt.Width := 200;
btn.Parent := frm;
btn.Caption := 'OK';
btn.Default := true;
btn.ModalResult := mrOk;
btn.Top := edt.Top + edt.Height + 8;
btn.Left := edt.Left + edt.Width - btn.Width;
frm.ClientHeight := btn.Top + btn.Height + 8;
frm.ClientWidth := edt.Left + edt.Width + 8;
if frm.ShowModal = mrOk then
ShowMessageFmt('Welcome, %s', [edt.Text]);
finally
frm.Free;
end;
end;