Board index » delphi » Dynamic controls

Dynamic controls

Hi

If I create (dynamicaly) a Timage componet how do I access
propertises like 'picture' which is not a common property like top/left/width?

Can you add a number to the dynamic controls name,like
Instance.name:=instance1;
instance1.picture:='c:\windows\circles.bmp;{instance works but not
knew name of instance1}

How do you link dynamic components onclick events to a common event hadler?
(so you can say 'if  instance1 do this' or 'if instance10 do'...............

All the above for Delphi 1 project.

procedure TForm1.Button2Click(Sender: TObject);
var
  Reference: TControlClass;
  Instance: Tcontrol;
  Text: array[0..255] of Char;
begin
  Reference := Timage;
  Instance := Reference.Create(Self);
  Instance.Parent := CreationArea;
  Instance.Left := 10;
  Instance.Top := 10;
  Instance.showhint:=true;
  Instance.hint:='Hint';
{Problem-->}{Instance.picture:='c:\windows\circles.bmp';}}
  if Instance is TWinControl then
    SendMessage(TWinControl(Instance).Handle, WM_SETTEXT, 0,
      Longint(StrPCopy(Text, TextProp.Text)));
end;
--
Stephen.

 

Re:Dynamic controls


Hi...

the answers are for Delphi 3, but I think it should work in Delphi 1 too.

Quote
>If I create (dynamicaly) a Timage componet how do I access
>propertises like 'picture' which is not a common property like

top/left/width?

Picture is not a 'common' property, it's a class. To get it to load a
picture do this:
MyImage1.Picture.LoadFromFile('c:\windows\circles.bmp');

See Help file on TPicture for details.

Quote

>Can you add a number to the dynamic controls name,like
>Instance.name:=instance1;

How about using TList or creating an array? Then you have:
var MyImages:array[1..MAXIMAGES];

...
for n:=1 to MAXIMAGES do
  MyImages[n]:=TImage.Create;
...
Now you can acess them through MyImages[n]....

The other way is to create a Tlist which dinamically changes size as you add
objects to it.
TList is a array of pointers, so you need something like:
type PImage=^TImage;
var MyList:TList;
     tempImage:TImage;
...
MyList:=TList.Create;
for n:=1 to MAXIMAGES do
 begin
   tempImage:=TImage.Create;
   MyList.Add(^tempImage);
 end;

access: MyList[n]^

Quote

>How do you link dynamic components onclick events to a common event hadler?

don't know yet. sorry.

Re:Dynamic controls


The message <6oj1ap$4e...@planja.arnes.si>
  from  "Bojan Cekrlic" <che...@bigfoot.com> contains these words:

Quote
> >How do you link dynamic components onclick events to a common event hadler?
> don't know yet. sorry.

I think it has something to do with,
Timage1.onclick :={procedure name and object type}
I have not got it quite right yet though.

I read in one of the help files
'If the user has assigned a handler to a control's OnClick event,
clicking the control results in that method being called. If no
handler is assigned, nothing happens.'
Hmmm.

Re:Dynamic controls


The message <6oj1ap$4e...@planja.arnes.si>
  from  "Bojan Cekrlic" <che...@bigfoot.com> contains these words:
Hi
<snip>
Having slept on the problem I think that you answer will not compile
and I have tried to explain why I think so.

Quote
> >If I create (dynamicaly) a Timage componet how do I access
> >propertises like 'picture' which is not a common property like
> top/left/width?
> Picture is not a 'common' property, it's a class. To get it to load a
> picture do this:
> MyImage1.Picture.LoadFromFile('c:\windows\circles.bmp');

This is the problem if 'MyImage1' is created dynamicaly it is not a
valid object
at compile time so the compiler (I think) look's at MyImage1 and
thinks it is a var
that it does not know about.
There is however a way of doing the above which I hope to post later
for intersted parties.
--
Stephen.

Re:Dynamic controls


In article <1998071512582677...@zetnet.co.uk>, Stephen Gear

Quote
<stephen.g...@zetnet.co.uk> writes:
>If I create (dynamicaly) a Timage componet how do I access
>propertises like 'picture' which is not a common property like
>top/left/width?

If you look in Delphi help for TImage, click on properties and Picture, you
will see that the property Picture is of type TPicture (ie an object). If you
click on TPicture, you will similarly see that it can have properties of
BitMap, Icon MetaFile, and Graphic (Graphic can hold any of the previous
three). TPicture also has a Method of LoadFromFile. If you click on Bitmap, it
also has a method of LoadFromFile.

What this means is that you could create a TBitmap, call its LoadFromFile and
then allocate it to a TImage with :-
MyBitMap := TBitMap.Create;
MyBitMap.LoadfromFile('whatever');
MyImage.Picture.BitMap := MyBitMap;

Or you could call the TPicture's LoadFromFile method directly (the method
obviously can find out what sort of file content it is) by coding
MyImage.Picture.LoadFromFile('whatever');

Quote
>Can you add a number to the dynamic controls name,like
>Instance.name:=instance1;
>instance1.picture:='c:\windows\circles.bmp;{instance works but not
>knew name of instance1}

The problem here is that a TImage picture is a TPicture, not a string. You
could say Instance1.Picture.LoadFromFile('whatever');,

I'm not sure why you declare a TControlClass and a TControl instead of coding
Instance := TImage.Create(Self).

Quote
>How do you link dynamic components onclick events to a common event hadler?
>(so you can say 'if  instance1 do this' or 'if instance10 do'...............

ThisInstance.OnClick := MyGenericOnClickHandler;

TForm1.MyGenericOnClickHandler(Sender : TObject);
begin
 . .  .etc
end;

Every event handler has a Sender parameter of type TObject, which is the base
(and safe) class for all event-causing objects. You usually want to access some
property of that object (small O) which is not in the base TObject class but
you know is in the object which causes the event. You can (and must to access
it) type-cast the Sender object to a descendant which contans the property you
want to access. so for you

if TImage(Sender).Name = Instance1 then . . . .
if TImage(Sender.Name = Instance2 then . . . .

Another way is to utilise the Tag property of all visual components, this is an
integer and you can put what you like in it. So at some prior stage set the Tag
:= some value less than 255. Then you can code

case Byte(MyImage.Tag) of  // case only handles values up to 255
1 : {code for image with tag of 1}
2 : {code for image with tag of 2}
 . . . etc
end;

BTW I would advise using meaningful names for your objects - not Instance. It
makes it _so_ much easier when you come back to the code six months later.

In article <1998071521265577...@zetnet.co.uk>, Stephen Gear

Quote
<stephen.g...@zetnet.co.uk> writes:
>I read in one of the help files
>'If the user has assigned a handler to a control's OnClick event,
>clicking the control results in that method being called. If no
>handler is assigned, nothing happens.'
>Hmmm.

All this means is
1 There is a private variable called FOnClick in the component which is
initialised to nil. When you allocate an event handle (called say
Button1OnClick) then the address of the Button1OnClick procedure is placed in
the FOnClick variable.

2 When the event happens there is a private method (a procedure called Click in
this case) which gets called by the event. It does anything else that is needed
by the COMPONENT privately and then has code :-

if Assigned(FOnClick) then FOnClick(Self);

 . . which means "if there is a value (not nil) in the FOnClick variable call
the procedure at that address. Use a parameter for the procedure of 'whatever
instance of the object is being dealt with at this time' (which is Self)".

So if you have nominated a procedure to be called by the event, it gets called.
If you haven't nominated a procedure, nothing happens.

Alan Lloyd
alangll...@aol.com

Other Threads