По подразбиране (т.е. с всички настройки за конфигурация на 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;
Or:
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 убие процеса.
person
NGLN
schedule
19.04.2013
Dialogs.CreateMessageDialog
за пример. - person NGLN   schedule 20.04.2013