fibdev
asked on
Need to determin TObject ClassType & Name
Hello,
I need to determine the ClassType and Name of the TObject created before the sender...
procedure MyProcedure(Sender: TObject);
var TheAnswer: TObject;
begin
If Sender.ClassType = TForm then
DoMyFormProcedure(TForm(Se nder))
else
// begin MyProcedure where I need TheAnswer
// Insert Code to Determine the TObject created before Sender
// Then I can use it...
end;
I need to determine the ClassType and Name of the TObject created before the sender...
procedure MyProcedure(Sender: TObject);
var TheAnswer: TObject;
begin
If Sender.ClassType = TForm then
DoMyFormProcedure(TForm(Se
else
// begin MyProcedure where I need TheAnswer
// Insert Code to Determine the TObject created before Sender
// Then I can use it...
end;
ASKER
Loki,
Yes, I did that... Let me update you!
Here is where I am now...
...
var ClassRef: TClass;
begin
// I wrote a function GetObject(Sender)
// It returns the object i need, but...
ClassRef := GetObject(Sender).ClassTyp e;
// this works... but
If ClassRef.ClassName(Sender) .Align = alLeft then
Align := 'left'; // I get *too many actual params*
...
function GetObject(Sender: TObject): TObject;
var I: Integer;
IT: TObject;
begin
oList := TObjectList.Create;
If oList.Count > 0 then
begin
for I := 0 to oList.Count - 1 do
begin
if oList.Items[I] = Sender then
IT := oList.Items[(I-1)];
end;
end;
Result := IT;
IT.Free;
end;
Yes, I did that... Let me update you!
Here is where I am now...
...
var ClassRef: TClass;
begin
// I wrote a function GetObject(Sender)
// It returns the object i need, but...
ClassRef := GetObject(Sender).ClassTyp
// this works... but
If ClassRef.ClassName(Sender)
Align := 'left'; // I get *too many actual params*
...
function GetObject(Sender: TObject): TObject;
var I: Integer;
IT: TObject;
begin
oList := TObjectList.Create;
If oList.Count > 0 then
begin
for I := 0 to oList.Count - 1 do
begin
if oList.Items[I] = Sender then
IT := oList.Items[(I-1)];
end;
end;
Result := IT;
IT.Free;
end;
ASKER
I noticed a problem and updated GetObject...
function GetObject(Sender: TObject): TObject;
var I: Integer;
IT: TObject;
sForm: TForm;
begin
sForm := Application.MainForm;
sForm.controls
If sForm.ControlCount > 0 then
begin
for I := 0 to sForm.ControlCount - 1 do
begin
if sForm.Controls[I] = Sender then
IT := sForm.Controls[(I-1)];
end;
end;
Result := IT;
IT.Free;
end;
function GetObject(Sender: TObject): TObject;
var I: Integer;
IT: TObject;
sForm: TForm;
begin
sForm := Application.MainForm;
sForm.controls
If sForm.ControlCount > 0 then
begin
for I := 0 to sForm.ControlCount - 1 do
begin
if sForm.Controls[I] = Sender then
IT := sForm.Controls[(I-1)];
end;
end;
Result := IT;
IT.Free;
end;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
This is a little better.
It stops once it finds teh object, so it is faster, and cleaner
function GetObject(Sender: TObject): TObject;
var
i, ourobjectindex: Integer;
begin
result := nil; // default
i := 0;
ourobjectindex := -1;
while (ourobjectindex = -1) and (i < Application.MainForm.Contr olCount) do
begin
if Application.MainForm.Contr ols[i] = Sender then
ourobjectindex := i
else inc(i);
end;
if ourobjectindex > 0 then // make sure this is not the first object in the list
result := Application.MainForm.Contr ols[ourobj ectindex-1 ];
end;
procedure TForm1.Button1Click(Sender : TObject);
var
anobject: tobject;
begin
anobject := getobject(button1);
if anobject <> nil then
showmessage( (anobject as twincontrol).name)
else
showmessage('object is the first in the list');
end;
It stops once it finds teh object, so it is faster, and cleaner
function GetObject(Sender: TObject): TObject;
var
i, ourobjectindex: Integer;
begin
result := nil; // default
i := 0;
ourobjectindex := -1;
while (ourobjectindex = -1) and (i < Application.MainForm.Contr
begin
if Application.MainForm.Contr
ourobjectindex := i
else inc(i);
end;
if ourobjectindex > 0 then // make sure this is not the first object in the list
result := Application.MainForm.Contr
end;
procedure TForm1.Button1Click(Sender
var
anobject: tobject;
begin
anobject := getobject(button1);
if anobject <> nil then
showmessage( (anobject as twincontrol).name)
else
showmessage('object is the first in the list');
end;
ASKER
Thanks,
I'll look at it after work
I'll look at it after work
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
function GetPrevObject(aParent: TWinControl; aObject: TObject): TObject;
var
a_iIndex: integer;
begin
Result := nil;
for a_iIndex := 0 to aParent.ControlCount -1 do
begin
{we loop through all the children}
if a_iIndex > 0 then
if aParent.Controls[a_iIndex] = aObject then
begin
Result := aParent.Controls[a_iIndex -1];
exit;//<--added to jump out faster...
end;
if (Result = nil) and (aParent.Controls[a_iIndex ] is TWinControl) then
{if its a WinControl...meaning it can be a Parent to other controls...we loop
through them, and so and so on.}
Result := GetPrevObject(TWinControl( aParent.Co ntrols[a_i Index]), aObject);
end;
end;
{Test code...remember to check if assigned before using the object...because can be nil...as in example }
procedure TForm1.Button2Click(Sender : TObject);
var
a_PrevObject: TObject;
begin
a_PrevObject := GetPrevObject(Form1, Sender);
if Assigned(a_PrevObject) then
if a_PrevObject is TButton then
TButton(a_PrevObject).Capt ion := 'Previous';
end;
var
a_iIndex: integer;
begin
Result := nil;
for a_iIndex := 0 to aParent.ControlCount -1 do
begin
{we loop through all the children}
if a_iIndex > 0 then
if aParent.Controls[a_iIndex]
begin
Result := aParent.Controls[a_iIndex -1];
exit;//<--added to jump out faster...
end;
if (Result = nil) and (aParent.Controls[a_iIndex
{if its a WinControl...meaning it can be a Parent to other controls...we loop
through them, and so and so on.}
Result := GetPrevObject(TWinControl(
end;
end;
{Test code...remember to check if assigned before using the object...because can be nil...as in example }
procedure TForm1.Button2Click(Sender
var
a_PrevObject: TObject;
begin
a_PrevObject := GetPrevObject(Form1, Sender);
if Assigned(a_PrevObject) then
if a_PrevObject is TButton then
TButton(a_PrevObject).Capt
end;
ASKER
Ok,
I've looked at both examples...
What I'm trying to do is use a property from the WinControl created before the one I reference as Sender. The hitch is... I want to do this without knowing the ClassType of said WinControl.
So givin, this won't do :(
if a_PrevObject is TButton then
TButton(a_PrevObject).Capt ion := 'Previous';
I'm trying to avoid a lengthy case statement that may or may not miss a WinControl.
I've looked at both examples...
What I'm trying to do is use a property from the WinControl created before the one I reference as Sender. The hitch is... I want to do this without knowing the ClassType of said WinControl.
So givin, this won't do :(
if a_PrevObject is TButton then
TButton(a_PrevObject).Capt
I'm trying to avoid a lengthy case statement that may or may not miss a WinControl.
if you want to use a property of a control, that's fine, eg. (anobject as tcontrol).parent or (anobject as twincontrol).bevelinner...
if you want to be specific and set a "caption" of a control, then you _will_ need to check if it has that property
(by "is tlabel" for example)
I would not recommend doing :-
try
(anonbect as tlabel).caption := 'test'; // anobject may not be a TLabel, so this will generate an error
except
end;
and ignoring the error when the typecast fails.
You might need to explain a bit more to us about what you are trying to do. Perhaps there is a more obvious solution we could provide.
if you want to be specific and set a "caption" of a control, then you _will_ need to check if it has that property
(by "is tlabel" for example)
I would not recommend doing :-
try
(anonbect as tlabel).caption := 'test'; // anobject may not be a TLabel, so this will generate an error
except
end;
and ignoring the error when the typecast fails.
You might need to explain a bit more to us about what you are trying to do. Perhaps there is a more obvious solution we could provide.
If your trying to change a Non Polymorphic property...there is no way around having to write some type of Type conversion...
but if your trying to change a Polymorphic property like Caption...
Label1.Caption := 'My Caption'
Caption is Polymorphic...it is in TControl...but protected...so you can do something like this
declare this in the Interface...
type
THackControl = class(TControl)
public
property Caption;
end;
Your code...
if Sender is TControl then
THackControl(Sender).Capti on := 'My Caption';
but if your trying to change a Polymorphic property like Caption...
Label1.Caption := 'My Caption'
Caption is Polymorphic...it is in TControl...but protected...so you can do something like this
declare this in the Interface...
type
THackControl = class(TControl)
public
property Caption;
end;
Your code...
if Sender is TControl then
THackControl(Sender).Capti
ASKER
I've givin the whole of my code to someone I trust and know to have vast knowlage of Delphi. He tells me that what I'm trying to do is not practical because the controls are listed in an arbitrary order.
Thank you guys for trying, but I think I'm going to take a different approach.
Thank you guys for trying, but I think I'm going to take a different approach.
What kind of objects are these? are they user created TSomeUnknownObject, or are they child objects of the form?
are they "controls" ?
If the object is in a list, you could iterate through the list comparing each, and return the value before the index of the object if you find it. If it's a form's control, you can use the form1.controls[i] list