Solved

Dynamic Creation of Objects

Posted on 2004-09-15
8
252 Views
Last Modified: 2010-04-05
I need to create DYNAMICALLY some objects within other objects. The pseudocode I want goes something like this:

// on click of a button

For iLoop := 1 to iNoOfPanelsToDo do
begin
  // Create a panel
  // give it a cyclic name ('panel001')
  // set its size and location on the form by Top := iLoop*20 etc.
  // Create a child panel on the above panel
  // give it a cyclic name ('innerpanel001')
  // set its size and location on the form
  // Create a button on the innerpanel
  // Attach procedure 'InnerButtonPressed' to the button's OnClick event
end;

I've stumbled through the Delphi Help but I cant seem to find anything like this in terms I've guessed to put in the search, yet I suspect it is something the more experienced Delphi people will know like the back of their hand. I did it before ages ago; all I can remember is the bit about accessing the dynamically-created components by name with FindComponent.

Sample code is best; I learn well from plagiarism; oops, I mean example.

Martin C  

0
Comment
Question by:MartinC
  • 4
  • 3
8 Comments
 
LVL 27

Accepted Solution

by:
kretzschmar earned 100 total points
ID: 12072454
var
  pi, po : TPanel;
  bt : TButton;
  i : integer;
begin
  for i := 1 to howmanyyouneed do
  begin
    po := TPanel.Create(self);
    with po do
    begin
       top := SomeOffset * i;
       left := whatUNeedHere;
       name := YourPrefix+inttostr(i); //usually name is not needed
       parent := self;
       //maybe more
       show; //maybe not needed
   end;
    pi := TPanel.Create(self);
    with pi do
    begin
       top := whatUNeedHere;
       left := whatUNeedHere;
       parent := po;
       //maybe more
       show; //maybe not needed
   end;
    bt := TButton.Create(self);
    with bt do
    begin
       top := whatUNeedHere;
       left := whatUNeedHere;
       parent := pi;
       onClick := YourPredefinedClickProc;
       //maybe more
       show; //maybe not needed
   end;
  end;
end;

just from head

meikl ;-)

0
 

Author Comment

by:MartinC
ID: 12122570
Meikl:

I got all that to work - thx! - except the line:

 onClick := YourPredefinedClickProc;

which says "[Error] uAssetFacet.pas(67): Incompatible types: 'method pointer and regular procedure'" ... I presume there is some way I am not defining the procedure ... I wrote it as:

procedure YourPredefinedClickProc;
begin
  beep;
  beep;
  beep;
end;

... and I have no idea where I am supposed to store its top line:

procedure YourPredefinedClickProc;

... which I cuurently have above the form's type declaration:

type
  TfrmAssetFacet = class(TForm)

... any idea where it should go?

 
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 12122801
well, glad to hear

about the error you get

redefine your proc to

procedure TFormClassName.YourPredefinedClickProc(Sender : TObject);
begin
  beep;
  beep;
  beep;
end;

you may notice TFormClassName
this means you should declare this procedure within your formtype like

type
  TfrmAssetFacet = class(TForm)
     .....
   private //could also public
     procedure YourPredefinedClickProc(Sender : TObject);
     ......
   end;

so that your proc becomes

procedure TfrmAssetFacet.YourPredefinedClickProc(Sender : TObject);
begin
  beep;
  beep;
  beep;
end;

hope you get it work

meikl ;-)
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

Author Comment

by:MartinC
ID: 12134724
I tried that before ... I have the declaration like this:

type
  TfrmAssetFacet = class(TForm)
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure YourPredefinedClickProc;
  end;

... then in the code I have:

       onClick := YourPredefinedClickProc;

... and later I have:

procedure TfrmAssetFacet.YourPredefinedClickProc;
begin
  beep;
  beep;
  beep;
end;

... but the compiler says:

[Error] uAssetFacet.pas(68): Incompatible types: 'Parameter lists differ'

... any clues?
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 12134858
an easy one (you just not read my comment carfully ;-)

replace this
procedure TfrmAssetFacet.YourPredefinedClickProc;
begin
  beep;
  beep;
  beep;
end;

with
procedure TfrmAssetFacet.YourPredefinedClickProc(Sender : TObject);  //just add the sender
begin
  beep;
  beep;
  beep;
end;

hope now you get it work

meikl ;-)
0
 
LVL 11

Assisted Solution

by:ZhaawZ
ZhaawZ earned 20 total points
ID: 12136023
don't forget to add sender also in public declaration of procedure ;)

  public
    { Public declarations }
    procedure YourPredefinedClickProc(Sender : TObject);
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 12136086
good point, ZhaawZ, overlooked this
0
 

Author Comment

by:MartinC
ID: 12142728
Sorry, normally I am a good copier but I missed that one. I've increased the points a bit (60 to 100) and chucked a tidbit to ZhaawZ for his correction, which no doubt would have tripped me up too.

Martin
0

Featured Post

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

830 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