Solved

Dynamic creation of controls

Posted on 1998-08-25
8
198 Views
Last Modified: 2010-04-04
Hi there,

Using Delphi 3, I wish to create an indeterminate number of controls(components) such as gauges, progress bars, edit boxes and place them on a form at runtime.

The idea is that the user can select the type of control from a list of controls, and place the control on the form where required, set the size etc.

Basically, I wish to create the controls in an array or list and be able to modify the properties and events as required. I know how to do this with single variables of type TGauge etc but cannot seem to get it to work in an array of type TControl.

Any ideas?

Thanks

Chris
0
Comment
Question by:ChrisBerry
  • 5
  • 3
8 Comments
 
LVL 10

Accepted Solution

by:
viktornet earned 100 total points
ID: 1337735
type
//This is important,,,set a type that is a class of TControl
  TControlClass = class of TControl;

  TForm1 = class(TForm)
    Panel1: TPanel;
    RbtnRadio: TRadioButton;
    RbtnButton: TRadioButton;
    RbtnEdit: TRadioButton;
    procedure RbtnRadioClick(Sender: TObject);
    procedure RbtnButtonClick(Sender: TObject);
    procedure RbtnEditClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
//This is important too...the class reference
    ClassRef: TControlClass;
    Counter: Integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.RbtnRadioClick(Sender: TObject);
begin
  ClassRef := TRadioButton;
end;

procedure TForm1.RbtnButtonClick(Sender: TObject);
begin
  ClassRef := TButton;
end;

procedure TForm1.RbtnEditClick(Sender: TObject);
begin
  ClassRef := TEdit;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ClassRef := TRadioButton;
end;

procedure TForm1.FormMouseDown(
  Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  NewCtrl: TControl;
  MyName: String;
begin
  NewCtrl := ClassRef.Create (self);
  NewCtrl.Visible := False;
  NewCtrl.Parent := self;
  NewCtrl.Left := X;
  NewCtrl.Top := Y;
  Inc (Counter);
  MyName := ClassRef.ClassName + IntToStr (Counter);
  Delete (MyName, 1, 1);
  NewCtrl.Name := MyName;
  NewCtrl.Visible := True;
end;
end.

Is this what you needed.....If you need I could send you the whole project so you can see how it looks like and what exactly is happening...
Actually what happens is that you declare a class reference of TControl and if clicked on the button then on the next click on the form a button would be created...if you click on radio button and assign it to the class reference then when you click on the form a radio button would be created.....

Regards,
Viktor Ivanov
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1337736
Actually this doesn't show how to do it with an arrya but you got the idea how to change the Class Reference to another control at run-time... I hope now you can build your array thing using the example above =)

Regards,
Viktor Ivanov
0
 

Author Comment

by:ChrisBerry
ID: 1337737
Hi Viktor,

Thanks for the reply. Looking at the code you have supplied it would appear to do nearly exactly as I wish, I do not need an array.

However two things.

1) I need to reference the controls at run time eg connect say a trackbar to a progress bar and

2) Using your example I am unable to assign any procedures to events. i.e. NewCtrl.OnMouseMove := MagicMouseMove; does not work as OnMouseMove is not recognised.

Any ideas?

If you wish to e-mail me anything my address is cjberry@global.co.za

Thanks

Chris

0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 10

Expert Comment

by:viktornet
ID: 1337738
Here is an example.....
public
    procedure MagicMouseMove(Sender: TObject; Shift: TShiftState; X,
        Y: Integer);
{...}
procedure TForm1.MagicMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
begin
    Caption := IntToStr(x)+','+IntToStr(y);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
{
  Instead of having Button1.OnMouseMove put your control instead of that like this....
  NewCtrl.OnMouseMove := MagicMouseMove;
}
    Button1.OnMouseMove := MagicMouseMove;
end;

I hope this helps =)

Regards,
Viktor Ivanov

0
 
LVL 10

Expert Comment

by:viktornet
ID: 1337739
>1) I need to reference the controls at run time eg connect say a trackbar to
>     a progress bar and

I'm not sure what you mean by connect TrackBar to a ProgressBar... Would you please tell me what exactly is that you are trying to do???

Regards,
Viktor Ivanov
0
 

Author Comment

by:ChrisBerry
ID: 1337740
Thanks for the reply.

1) I am not sure what you mean by:-
 
  Instead of having Button1.OnMouseMove put your control instead of that like this....
  NewCtrl.OnMouseMove := MagicMouseMove;
}
    Button1.OnMouseMove := MagicMouseMove

I have tried this but it is rejected by the compiler because NewCtrl does not have a recognised property OnMouseMove. The only way I have been able to achieve this is to use:-

(NewCtrl as TButton).OnMouseMove but this is a problem because it is not generic to all controls. Now NewCtrl must know what type of control it is, is it not possible to use this informarion or the information contained in ClassRef?

2) TrackBar to ProgressBar. Say I create both a TrackBar and a ProgressBar at runtime and wish to connect the output of the TrackBar to the input value (Position) of the ProgressBar. I wish to be able to do this by the operator using a PopUp Menu on the ProgressBar where he has the option to select a source component for input, the TrackBar in this case. Again I think it is one of being able to address the component in a generic fashion. Hope this is clearer.

Thanks once again.

Regards

Chris
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1337741
Hello Chris =)

If the project is not too big you could send it to me so I can see what exactly is going on and can write the code right in there so I can try it myself... My e-mail is viktor@megsinet.net
I'm going to school today so I'll maybe able to answer later in the evening :(

Regards,
Viktor Ivanov
0
 

Author Comment

by:ChrisBerry
ID: 1337742
Hi Viktor,

Please send me a small message at cjberry@global.co.za as I am unable to send to the address you have specified above (not recognised!!!). I will then reply with the project file.

Thanks

Chris

0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question