Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2021-12

Assigning Class to object

4 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Steve Gatenby

Please dont judge on simplicity of question (or questioner) -  :)

if I call the following procedure with either a TButton or Panel ctrl (for example), how can I use the class info contained within the MyObj to choose the correct Class

procedure SetThis( MyObj :TObject );
begin
   // this works -
   if pos('Button', MyObj.ClassName) > 0
   then TButton(MyObj).OnMouseDown := tmethod (not important here)
   else TButton(MyObj).OnMouseDown := tmethod; (not important here)

  // what I would like is the single assignment as could cover multiple controls / events
  TClass(MyObj).OnMouseDown := tmethod (not important here)

end;

Regards SteveG

Reply by email

R.Smith
to Steve Gatenby
if I call the following procedure with either a TButton or Panel ctrl

(for example), how can I use the class info contained within the MyObj to choose the correct Class

Two things,

Firstly the correct way of determinig class (as with your current solution) is like this:

  if (MyObj is TButton) then TButton(MyObj).OnMouseDown := tmethod (not important here)  else
  if (MyObj is TPanel)  then TPanel(MyObj).OnMouseDown := tmethod (not important here)  else
  //  etc...

If you want to change a property/method of many descendants of class which all contain the same property, that is quite easy and what object orientation is great at, but you have to figure out what is the most recent ancestor class that is the ancestor of all the classes that you wish to treat similarly, AND if the property(ies) are defined in the ancestor or higher.  This is trivial to do just looking through the FPC help/documentation pages for the classes in question.

In the case you describe, from memory I believe TControl is the recent-most ancestor of both those classes that already has the OnMouseDown event defined, so this should work:

procedure SetThis( MyObj :TObject );
begin
   TControl(MyObj).OnMouseDown := @someMouseDownMethod;
end;

HTH.

Reply by email

Steve Gatenby
to R.Smith

Thank you, that should work for me :)

R.Smith wrote 37 lines
> if I call the following procedure with either a TButton or Panel ctrl (for example), how can I use the class info contained within the MyObj to choose the correct Class Two things, Firstly the correct way of determinig class (as with your current solution) is like this:   if (MyObj is TButton) then TButton(MyObj).OnMouseDown := tmethod (not important here)  else   if (MyObj is TPanel)  then TPanel(MyObj).OnMouseDown := tmethod (not important here)  else   //  etc... If you want to change a property/method of many descendants of class which all contain the same property, that is quite easy and what object orientation is great at, but you have to figure out what is the most recent ancestor class that is the ancestor of all the classes that you wish to treat similarly, AND if the property(ies) are defined in the ancestor or higher.  This is trivial to do just looking through the FPC help/documentation pages for the classes in question. In the case you describe, from memory I believe TControl is the recent-most ancestor of both those classes that already has the OnMouseDown event defined, so this should work: procedure SetThis( MyObj :TObject ); begin   TControl(MyObj).OnMouseDown := @someMouseDownMethod; end; HTH.

Reply by email

Kostas Michalopoulos
to R.Smith: (for example), how can I use the class info contained within the MyObj to choose the…
R.Smith wrote 9 lines
Firstly the correct way of determinig class (as with your current solution) is like this:   if (MyObj is TButton) then TButton(MyObj).OnMouseDown := tmethod (not important here)  else   if (MyObj is TPanel)  then TPanel(MyObj).OnMouseDown := tmethod (not important here)  else   //  etc...

One small detail is that the "is Thing" operator checks if the object belongs to the class hierarchy introduced by the Thing class, but not necessarily if it *is* of Thing type - it can be a subclass too. Sometimes this distinction is important, so in those cases instead of "is" you can use the ClassType property of objects (e.g. if MyObj.ClassType=TButton then ...).

(yeah the name of the operator is kinda optimistic in assuming Liskov substitution principle always applies, but in practice this is often not the case :-P)

In general assuming two f: TFoo and b: TBar objects with TBar being a subclass of TFoo, this code:

Writeln(f is TFoo, ' ', b is TFoo, ' ',
         f.ClassType=TFoo, ' ', b.ClassType=TFoo);

Will write TRUE TRUE TRUE FALSE (ie, both f and b belong to the class hierarchy introduced by TFoo but only f is really TFoo and b is not).

Kostas

Reply by email