Jump to content
JIMSMITH

creating a frame at runtime

Recommended Posts

I have 5 frames that I want to create at runtime.  The frames are descended from tframe2 or tframe3 how can I create this and allow the type (tframe2 or tframe3) to be specified in a variable.? So the object will be specified in a variable and the type will be in a variable as well.  So tframe2 and tframe3 will be defined and created at runtime, but the actual frame and descendant from type would be in a variable.

Share this post


Link to post

TFrame has a virtual constructor, so you can use a meta class variable for this task, eg:

type
  TFrameClass = class of TFrame;

var
  Frame: TFrame;
  FrameClass: TFrameClass;
begin
  ...
  if SomeCondition then
    FrameClass := TFrame2;
  else
    FrameClass := TFrame3;

  Frame := FrameClass.Create(Owner);
  ...
end;

 

 

Edited by Remy Lebeau

Share this post


Link to post

Note that the Frame instance should have its parent set to Owner as well.

 

Share this post


Link to post

Don't forget to set the Name property of your frame to something unique.

Otherwise, it will throw a runtime exception when you have several components with identical name in the same container.

Share this post


Link to post
1 hour ago, Der schöne Günther said:

Don't forget to set the Name property of your frame to something unique.

Otherwise, it will throw a runtime exception when you have several components with identical name in the same container.

Or to an empty string. It's the safest and easiest way, in my opinion.

Edited by havrlisan
  • Like 1
  • Thanks 2

Share this post


Link to post
2 minutes ago, Der schöne Günther said:

Didn't even know that was possible.

It is even possible at design time. Setting an empty name to a component will remove the corresponding field in the class. It is often used with TLabel instances that only exist to display some static text, but won't be accessed in the code. It reduces code cluttering a bit.

  • Like 3
  • Thanks 3

Share this post


Link to post
9 minutes ago, Uwe Raabe said:

It is even possible at design time. Setting an empty name to a component will remove the corresponding field in the class. It is often used with TLabel instances that only exist to display some static text, but won't be accessed in the code. It reduces code cluttering a bit.

Interesting! I never thought of that. I learned something new today 😁 I'll definitely have to play with this in my projects.

Edited by Remy Lebeau

Share this post


Link to post

When using frame inheritance, be aware that running Delphi at high DPI can cause issues, which might negatively affect the layout and functionality of your frames.

 

To avoid these issues, you can run Delphi in DPI-unaware mode:

"C:\Program Files (x86)\Embarcadero\Studio\23.0\bin\bds.exe" /highdpi:unaware

Share this post


Link to post
2 hours ago, Uwe Raabe said:

It is even possible at design time. Setting an empty name to a component will remove the corresponding field in the class. It is often used with TLabel instances that only exist to display some static text, but won't be accessed in the code. It reduces code cluttering a bit.

This can be a problem in a multilingual project

Share this post


Link to post
2 hours ago, tgbs said:

This can be a problem in a multilingual project

In that case, the text is not static 😉

 

  • Haha 1

Share this post


Link to post
21 hours ago, Der schöne Günther said:

set the Name property of your frame to something unique

I use a global function GetNextInstanceNumber to get and increment a integer variable and just set the name to Self.ClassName+'_'+GetNextInstanceNumber.ToString;

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×