Board index » delphi » Typecasting?

Typecasting?


2004-01-22 06:06:09 PM
delphi60
Hi guys!
I have 2 own components:
MyLabel = class(TLabel)
private
protected
public
procedure DoSomething(something:string);
published
end;
MyEdit = class(TEdit)
private
protected
public
procedure DoSomething(something:string);
published
end;
Both of them has a DoSomething procedure.
I put some MyEdit and MyLabel components to a new form and in the form.create i go through the components on the form (i know that only MyLabel and MyEdit type components are on the form) with the following code:
for k:=0 to ControlCount-1 do
Controls[k].DoSomething(something);
And this is where the problems starts. Controls[k] type is TControl, so the compiler thinks it doesnt have DoSomething procedure. I know that Controls[k]'s type can be only MyLabel and MyEdit (which do have DoSomething procedure) and maybe i should use some kind of typecasting here but i dont know how/what.
Can u help me what should i do/how should i do exactly?
Thanx in advance,
Zsolt
p.s: please post the answer to my email-addy, also, thanx
 
 

Re:Typecasting?

You may TypeCast the ComponentClass :
For k:=0 to ControlCount-1 do
begin
if (Controls[K] is MyLabel)
then (Controls[K] as MyLabel).DoSomething(something);
if (Controls[K] is MyEdit)
then (Controls[K] as MyEdit).DoSomething(something);
End;
One avantage of such an implementation is that every component is tested
before calling a procedure.
Regards,
Florent
"Zsolt" <XXXX@XXXXX.COM>a écrit dans le message de
Quote

Hi guys!

I have 2 own components:
MyLabel = class(TLabel)
private
protected
public
procedure DoSomething(something:string);
published
end;

MyEdit = class(TEdit)
private
protected
public
procedure DoSomething(something:string);
published
end;

Both of them has a DoSomething procedure.
I put some MyEdit and MyLabel components to a new form and in the
form.create i go through the components on the form (i know that only
MyLabel and MyEdit type components are on the form) with the following code:
Quote

for k:=0 to ControlCount-1 do
Controls[k].DoSomething(something);

And this is where the problems starts. Controls[k] type is TControl, so
the compiler thinks it doesnt have DoSomething procedure. I know that
Controls[k]'s type can be only MyLabel and MyEdit (which do have DoSomething
procedure) and maybe i should use some kind of typecasting here but i dont
know how/what.
Quote

Can u help me what should i do/how should i do exactly?

Thanx in advance,
Zsolt

p.s: please post the answer to my email-addy, also, thanx

 

Re:Typecasting?

Quote
if (Controls[K] is MyLabel)

then (Controls[K] as MyLabel).DoSomething(something);

if (Controls[K] is MyEdit)

then (Controls[K] as MyEdit).DoSomething(something);

End;

One avantage of such an implementation is that every component is tested
before calling a procedure.
Yeah, but the problem with this solution is that i have about 15-20 own components not only that 2 (so i should write 15-20 'if'), and i should use this kind of code a lot of times in my program. So, it would be a bit difficult in this case :(
 

Re:Typecasting?

Zsolt writes:
Quote
>if (Controls[K] is MyLabel)
>
>then (Controls[K] as MyLabel).DoSomething(something);
>
>if (Controls[K] is MyEdit)
>
>then (Controls[K] as MyEdit).DoSomething(something);
>
>End;
>
>One avantage of such an implementation is that every component is tested
>before calling a procedure.


Yeah, but the problem with this solution is that i have about 15-20 own components not only that 2 (so i should write 15-20 'if'), and i should use this kind of code a lot of times in my program. So, it would be a bit difficult in this case :(
Well, if You'd make the method published...
MyLabel = class(TLabel)
published
procedure DoSomething(something:string);
end;
TDoSomethingEvent = procedure (something:string) of object;
and then
var
DoSome: TDoSomethingEvent;
k: Integer;
begin
for k:=0 to ControlCount-1 do
begin
TMethod(DoSome).Code := Controls[k].MethodAddress('DoSomething');
if TMethod(DoSome).Code <>nil then
begin
TMethod(DoSome).Data := Controls[k];
DoSome('something');
end;
end;
--
Gert
 

Re:Typecasting?

Florent Ouchet writes:
Quote
For k:=0 to ControlCount-1 do

begin

if (Controls[K] is MyLabel)
then (Controls[K] as MyLabel).DoSomething(something);

if (Controls[K] is MyEdit)
then (Controls[K] as MyEdit).DoSomething(something);

End;
It's very inefficient to use both IS and AS in the same test - if an
object is a TMyLabel then you can safely directly typecase it.
Also it is normal convention to preface all type definition names with T.
for k := 0 to ControlCount - 1 do
begin
if Controls[ k ] is TMyLabel then
TMyLabel( Controls[ k ] ).DoSomething( something )
else if Controls[ k ] is TMyEdit then
TMyEdit( Controls[ k ] ).DoSomething( something );
end;
John Leavey
 

Re:Typecasting?

Zsolt writes:
Declare an interface
IDoSomething = interface
preocedure DoSomething(something: string);
end;
Then declare your classes like this:
MyLabel = class(TLabel, IDoSomething)
private
protected
public
procedure DoSomething(something:string);
published
end;
MyEdit = class(TEdit, IDoSomething)
private
protected
public
procedure DoSomething(something:string);
published
end;
Then you can call
var
DS: IDoSomething
begin
for k := 0 to ControlCount - 1 do
begin
if Supports(Controls[k], IDoSomething, DS) then
begin
DS.DoSomething;
end;
end;
--
Nick Hodges (TeamB)
Lemanix Corporation - (www.lemanix.com)
Improve the quality of Delphi! Get your bugs into QC:
qc.borland.com
 

Re:Typecasting?

I had such a solution using an interface but i didn't know the "Supports"
function.
Thanks Nick,
Florent.
"Nick Hodges (TeamB)" <XXXX@XXXXX.COM>a écrit dans le message de
Quote
Zsolt writes:


Declare an interface

IDoSomething = interface
preocedure DoSomething(something: string);
end;

Then declare your classes like this:




MyLabel = class(TLabel, IDoSomething)
private
protected
public
procedure DoSomething(something:string);
published
end;

MyEdit = class(TEdit, IDoSomething)
private
protected
public
procedure DoSomething(something:string);
published
end;

Then you can call

var
DS: IDoSomething
begin
for k := 0 to ControlCount - 1 do
begin
if Supports(Controls[k], IDoSomething, DS) then
begin
DS.DoSomething;
end;
end;



--
Nick Hodges (TeamB)
Lemanix Corporation - (www.lemanix.com)
Improve the quality of Delphi! Get your bugs into QC:
qc.borland.com