Search code examples
functionoopdelphiinheritanceprocedure

Passing inherited frames as argument to a procedure


I have a TPageControl with N amount of TTabSheets in my main form which I use to embed several TFrame descendants. For the frames I created a "TBaseFrame" from which I derive the individual frames which I want to display in the TabSheets, more or less looks like this...

TBaseFrame = class(TFrame)

  • TBaseFrameDescendant1 = class(TBaseFrame)
  • TBaseFrameDescendant2 = class(TBaseFrame)
  • TBaseFrameDescendantN = class(TBaseFrame)

What im struggleing with is this: I want to create a procedure that takes any of my TBaseFrameDescendants as an argument, creates the given frame and displays it in a new tab sheet. I started with something like this...

procedure CreateNewTabSheetAndFrame( What do I put here to accept any of my TBaseFrameDescendants? )
var
  TabSheet: TTabSheet;

begin
  TabSheet := TTabSheet.Create(MainPageControl);
  TabSheet.Caption := 'abc';
  TabSheet.PageControl := MainPageControl;

// Here I want to create the given TBaseFrameDescendant, set the Parent to the above TabSheet and so on   
end;

Guess my main question here is how to set up my procedure so I can pass in any frame which is derived from my TBaseFrame so I can work with it within the procedure, or am I heading in the wrong direction here?


Solution

  • You need to use what is known as a metaclass.

    type
      TBaseFrameClass = class of TBaseFrame;
    
    procedure TMainForm.CreateNewTabSheetAndFrame(FrameClass: TBaseFrameClass)
    var
      TabSheet: TTabSheet;
      Frame: TBaseFrame;
    begin
      TabSheet := TTabSheet.Create(Self);
      TabSheet.PageControl := MainPageControl;
      Frame := FrameClass.Create(Self);
      Frame.Parent := TabSheet;
    end;
    

    Make sure that if you declare any constructors in any of your frame classes, that they derive from the virtual constructor introduced in TComponent. That is necessary in order for the instantiation via metaclass to invoke the appropriate derived constructor.