I have a Modal form, and in the Ok button it processes some information, that I need in the form that called the modal form.
How can I get it out before it closes?
Or delay the close till I say it can close.
I have a Modal form, and in the Ok button it processes some information, that I need in the form that called the modal form.
How can I get it out before it closes?
Or delay the close till I say it can close.
I expect that your OK button has ModalResult
set to mrOK
. If you want to add error checking to the OK button then change that to mrNone
. Add an OnClick
handler to the button which does whatever checking or processing you need. If it determines that the form can close, set Self.ModalResult := mrOK
in the OnClick
handler.
Do you really need to access the information before the form is closed? Delaying the closing of a form will affect the users experience of the app (unless it's fast enough that they don't notice - in which case why delay it at all?)
A closed form is still available in memory for the caller (unless the close action is caFreeOnClose). So you should be able to add public properties to the form which you can then access within the caller.
e.g
Type Form2 = Class(TForm)
public
//Add a public property here
end;
From the caller:
if Form2.ShowModal = mrOk then
begin
InformationIWant = Form2.PublicProperty;
end;
Just a combination of what others are saying.
It is a good idea to formalize how to validate and get data out from a modal dialog. Using the same technique over and over again makes everything easier to maintain and read.
An example :
Type TFormModal = Class(TForm)
procedure OnOkClick( Sender : TObject);
function ValidateInterface : boolean;
public
procedure SetInterface( input data here);
procedure GetInterface( output data here);
end;
procedure TFormModal.OnOkClick( Sender : TObject);
begin
if ValidateInterface
then modalResult := mrOk
else modalResult := mrNone;
end;
from your main form :
procedure MainForm.OnShowMyModalFormClick( sender : TObject);
var
myModal : TFormModal;
begin
...
myModal := TFormModal.Create( nil);
try
myModal.SetInterface( ...);
if (myModal.ShowModal = mrOk) then myModal.GetInterface(...);
finally
myModal.Free;
end;
...
end;
As addition to JamesB's answer.
You must call Form2.Free, áfter you take the information you want.
I generally add a new function to the second form's unit, something like:
type
TForm2 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
InformationIWant : SomeType;
end;
var
Form2: TForm2;
function ReturnValue : SomeType
implementation
function ReturnValue : Sometype;
begin
try
if Form2 = nil then
Form2 := TForm2.Create(nil);
Form2.Windowstate := wsNormal;
Form2.BringToFront;
SetForegroundWindow(Application.Handle);
if Form2.ShowModal then
Result := InformationIWant
finally
FreeAndNil(Form2);
end;
end;
An alternative to David’s answer is to use either OnClose
or OnCloseQuery
events. With OnCloseQuery
you can prevent the form from closing by setting CanClose := false;
Let's say you want to do more than to simply know if the user pressed the OK or Cancel button in your modal from.
Let's suppose you need to set some parameters for the MainFrom in FromSettings.
Of course the MainFrom has to have some exposed (public) fields in which you receive the data from FormSettings, like:
FormMain.AlphaBlendValue := FormSettings.spnTransparency;
Hint 1:
You don't necessary have to transfer data from FormSettings into MainForm. If it better suits you, you can also save the data in a global variable, or record.
Hint 2:
I personally don't use the method described above, which is designed to save RAM when the FormSettings is freed.
I actually never destroy the SettingsForm. Some people would say that this is "horror" but computers today have 4GB or RAM (at least) and a form with some controls on it will "waste" a very very little amount of that RAM. So, the FormSettings in is memory all the time. When I need some values, I just let the MainForm to read them from FormSettings.
Again... this is definitively the recommended way to do it. It is the convenient way :) You have been warned!