Display MDI form as modal
This will sound against the nature of MDI. I sometimes need to display an MDI form (FormStyle = fsMdiChild). And I also need to access the part between Application.CreateForm and OnShow events of another MDI form, i.e.
Application.CreateForm(Form2,TForm2); // but don't set form2 visible property true.
Form2.caption:='not working example';
Form2.SomeMagicToSetVisibleTrue;
Any ideas?
source to share
For your first problem: add another constructor like CreateAsMDI like:
constructor TModalAndMDIForm.CreateAsMDI(AOwner: TComponent);
begin
f_blChild := true;
GlobalNameSpace.BeginWrite;
try
inherited CreateNew(AOwner);
if(not(csDesigning in ComponentState)) then begin
Include(FFormState, fsCreating);
try
FormStyle := fsMDIChild;
if(not(InitInheritedComponent(self, TForm))) then
raise Exception.CreateFmt('Can't create %s as MDI child', [ClassName]);
finally
Exclude(FFormState, fsCreating);
end;
end;
finally
GlobalNameSpace.EndWrite;
end;
end;
In a normal constructor, just set the f_blChild variable to false and call inherited creation.
You need two more things, and I'll explain myself:
procedure TModalAndMDIForm.Loaded;
begin
inherited;
if(f_blChild) then
Position := poDefault
else begin
Position := poOwnerFormCenter;
BorderStyle := bsDialog;
end;
end;
//-----------------------------------------------------------------------------
procedure TModalAndMDIForm.DoClose(var Action: TCloseAction);
begin
if(f_blChild) then
Action := caFree;
inherited DoClose(Action);
end;
You can now call the modal form if it was created with a standard constructor, and as a child MDI if it was created with CreateAsMDI.
If you include this in your form declaration
property IsChild: boolean read f_blChild;
you can even do something depending on whether the form is an MDI child or not by simply interrogating the isChild property.
As for your second problem, don't use Application.CreateForm, but create your form yourself:
Here are two creations for modals and MDIs:
//Modal
frmDialog := TMyForm.Create(self);
// Your Code
frmDialog.ShowModal;
frmDialog.Release;
//MDI-Child
frmDialog := TMyForm.CreateChild(self);
// Your code
frmDialog.Show;
I have translated this answer to the DelphiPraxis article .
source to share
At least for Delphi 2007 and 2009, creating an MDI child form is imperceptibly easy. For early Delphi versions (where it is not possible to set Visible
in False
in the property inspector), you just need to provide a handler for the event OnCreate
and access the protected class field:
procedure TMDIChild.FormCreate(Sender: TObject);
begin
FFormState := FFormState - [fsVisible];
end;
This will disable the automatic rendering of the MDI child. After you're done with your other initializations, you can simply Show
or set Visible
to True
.
I will not attempt to answer your question about MDI modal child forms as it violates Windows platform conventions.
source to share
No answers are actually required. The best answer is wrong because the following:
- Opening the first form;
- Enlarge it;
- Now let's say that this form invokes another form (mdi);
- When constructed in the same way, you will get a buggy mock ... (it will be mdi-child, but not maximized, however the first one will still be maximized). So, the state of the buggy.
If you really need to decide at runtime whether fsMDIChild or fsNormal needs to be followed the following approach.
- You have a form that is stored as fsNormal in the design (or vice versa);
- Override InitializeNewForm method;
- Set the FFormStyle value for fsMDIChild (as shown below).
...
TYourForm = class(TForm)
...
protected
procedure InitializeNewForm; override;
...
procedure TYourForm.InitializeNewForm;
var
FS: ^TFormStyle;
begin
inherited;
if DoYourCheckForMDI then
begin
FS := @FormStyle;
FS^ := fsMDIChild;
end;
end;
source to share