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?

+2


source to share


4 answers


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 .

+4


source


The easiest way is to create a trivial form subclass and set

FormStyle = fsMDIChild

AND



Form .Visible = False

in the property inspector. It's tested and verified!

+2


source


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.

+1


source


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;

      

+1


source







All Articles