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)
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?
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.