Discussion:
Typecasting?
(too old to reply)
Zsolt
2004-01-22 10:06:09 UTC
Permalink
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
Florent Ouchet
2004-01-22 12:01:48 UTC
Permalink
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
Post by Zsolt
Hi guys!
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
Post by Zsolt
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.
Post by Zsolt
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
Zsolt
2004-01-22 13:45:20 UTC
Permalink
Post by Florent Ouchet
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 :(
Gert Kello
2004-01-22 15:04:21 UTC
Permalink
Post by Zsolt
Post by Florent Ouchet
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
John Leavey
2004-01-22 15:21:07 UTC
Permalink
Post by Florent Ouchet
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's 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
Nick Hodges (TeamB)
2004-01-24 03:01:24 UTC
Permalink
Zsolt wrote:


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 - (http://www.lemanix.com)
Improve the quality of Delphi! Get your bugs into QC:
http://qc.borland.com
Florent Ouchet
2004-01-24 11:21:06 UTC
Permalink
I had such a solution using an interface but i didn't know the "Supports"
function.

Thanks Nick,

Florent.
Post by Nick Hodges (TeamB)
Declare an interface
IDoSomething = interface
preocedure DoSomething(something: string);
end;
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 - (http://www.lemanix.com)
http://qc.borland.com
Loading...