Search code examples
delphimdi

Showing MDI form as modal


This will sound against the nature of MDI.. I need to show a MDI form (FormStyle=fsMdiChild) as modal sometimes. And I also need to access the part between Application.CreateForm and OnShow event of another MDI form, i.e.

Application.CreateForm(Form2,TForm2); // but don't set form2's visible property true.
Form2.caption:='not working example'; 
Form2.SomeMagicToSetVisibleTrue;

Any ideas?


Solution

  • For your first problem: Add another constructor, for example CreateAsMDI, like this:

    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 the normal constructor just set the variable f_blChild to false and call the inherited create.

    You need two more things, rather self explaining:

    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; 
    

    Now you can call the form modal, if created with the standard constructor, and as MDI child, if created with CreateAsMDI.

    If you include this in your form's declaration

    property IsChild: boolean read f_blChild; 
    

    you can even do things depending on whether the form is an MDI child or not, just interrogating the isChild property.

    As for your second problem: do not use Application.CreateForm, but create your form yourself:

    Here the two creations for modal and MDI:

    //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 form an article on the site DelphiPraxis.