I believe wp's example will show the structure very well. I just want to add some more explanations, hoping that it would be easier for you to understand.
When you want to display another form (let's say Form2) from original form (let's say Form1), you can use
Form2.Show; This will show Form2. But you can go back to Form1 while Form2 is floating.
And if you call
Form2.ShowModal; then you have to close this form in order to go back to your original form (Form1).
In order to close a modal form, you can call Close or set the form's ModalResult property to any value of TModalResult type.
There are several TModalResults values like mrNone, mrAll, mrCancel, mrOK, mrAbort, mrRetry, mrIgnore, mrYes, mrNo.
So you can close shown-modal form in one of following ways. But if you assign
ModalResult := mrNone then the form will not be closed.
procedure TForm2.Button1Click(Sender: TObject);
begin
Close;
// or
ModalResult := mrOK; // or mrCancel, mrNo, mrYes, etc. but mrNone will not close the form.
end;
Now, in the calling program, you will need the content in the modal form (form2) or not. So, if you have ALREADY CREATED form2, then following will work (and form2 is still stay in memory.
procedure TForm1.Button1Click(Sender: TObject);
begin
if Form2.ShowModal = mrOK then begin
Edit1.Text := Form2.Edit1.Text; // here, first Edit1 is Self.Edit1, which is in the form.
Edit2.Text := Form2.Edit2.Text; // Edit2,
AnyField := Form2.AField; // Anyfield as well.
end;
end;
In the above example, the key is :
if Form2.ShowModal = mrOK Which will be called when form2 returns modalresult, i.e. when the form is closed. The form is CLOSED but still ALIVE in memory.
The codes within the if block will be executed only when the modal form (form2) was closed with mrOK, but will not be executed if form was closed with modal results of mrCancel, mrYes, etc. If you have put two buttons on TForm2, one with OK and another with Cancel, then you will want update form1's content when the user clicked OK button but not Cancel button. To do that ModalResult will be assigned different values depending on the clicked button.
Here, you can set it up in a few different ways.
You may define different event handler for the two buttons:
procedure TForm2.Button1Click(Sender);
procedure TForm2.Button2Click(Sender); or, you may use one single event handler for both buttons.
procedure TForm2.Button1Click(Sender);
begin
if Sender = Button1 then ModalResult := mrOK
else if Sender = Button2 then ModalResult := mrCancel;
end; Or you can set
ModalResult property of buttons directly at the object inspector at design time.
And if you close Form2 by calling Close, not assigning ModalResult, then the codes will not be executed.
There are cases when you do not want to pre-create form2. You may want to create it only when it is necessary.
You'd better get familiar with following structure.
procedure TForm1.Button2Click(Sender: TObject);
begin
with TForm2.Create (nil) do begin // an instance is created here,
try
if ShowModal = mrOK then begin
Self.Edit1.Text := Edit1.Text; // First Edit1 needs Self. Without self, it will be regarded as TForm2's Edit1, as the second Edit1,
Self.Edit2.Text := Edit2.Text; // because this code is within with-block .
Self.AnyField := AField;
end;
finally
Free; // and the instance is freed here.
end;
end;
end;
Well, these are what I had most difficulty when I first tried to use modal forms. Good Luck.