Search code examples
delphigenericsvclmdi

How to Create MDI Child of different type with Generics?


I need to centralize the MDI Child Forms creation into a unique procedure in Delphi (VCL). The idea is to do some actions every time an MDI Child Form is created no matter its type, i.e., to add its caption name into a List to get access to that MDI child form. Like this:

   procedure TMainForm<T>.CreateMDIChild(const ACaption : String);
    var
      Child: T;
    begin
      { create a new MDI child window }
      Child := T.Create(Application);
      Child.Caption := ACaption;
      // add this child to the list of active MDI windows
      ...
    end;

   procedure TMainForm.Button1Click(Sender : TObject);
   begin
       CreateMDIChild<TMdiChild1>('Child type 1');
       CreateMDIChild<TMdiChild2>('Child type 2');
       ...

But, I don't have experience with generics. Any help I'll appreciate it. Thank you so much.


Solution

  • You can define a class for generic creation of form (using generics) with a class constraint like this:

    TGenericMDIForm <T:TForm> = class
      class procedure CreateMDIChild(const Name: string);
    end;
    

    And with this implementation:

    class procedure TGenericMDIForm<T>.CreateMDIChild(const Name: string);
    var
      Child:TCustomForm;
    begin
      Child := T.Create(Application);
      Child.Caption := Name + ' of ' + T.ClassName + ' class';
    end;
    

    Now, you can use it for create MDIChil forms differents classes:

    procedure TMainForm.Button1Click(Sender: TObject);
    begin
       TGenericMDIForm<TMdiChild>.CreateMDIChild('Child type 1');
       TGenericMDIForm<TMdiChild2>.CreateMDIChild('Child type 2');
    end; 
    

    Using the class constraint with the generic TGenericMDIForm <T:TForm> = class, you can avoid someone try use something like this TGenericMDIForm<TMemo>.CreateMDIChild('Child type 1'); with a class that not is a TForm descendant.