How to use "Sender" parameter with "As" operator for more then one class at a time?

Please_Dont_Bully_Me_SO_Lords picture Please_Dont_Bully_Me_SO_Lords · Jul 5, 2012 · Viewed 17.6k times · Source

In Delphi, sometimes we need to do this...

function TForm1.EDIT_Click(Sender: TObject);
begin
  (Sender As TEdit).Text := '';
end;

...but sometimes we need to repeat the function with other object class like...

function TForm1.COMBOBOX_Click(Sender: TObject);
begin
  (Sender As TComboBox).Text := '';
end;

...because the operator As does not accept flexibility. It must know the class in order to allow the .Text that come after the ().

Sometimes the code gets full of similar functions and procedures because we need to do the same thing with similar visual controls that we can't specify.

This is only an case of use example. Generally I use these codes on more complex codes to achieve a standard objective on many controls and other kind of objects.

Is there an alternative or trick to make these tasks more flexible?

Answer

Remy Lebeau picture Remy Lebeau · Jul 5, 2012

Use RTTI to perform common tasks on similarly-named properties of unrelated classes, eg:

Uses
 ..., TypInfo;

// Assigned to both TEdit and TComboBox
function TForm1.ControlClick(Sender: TObject);
var
  PropInfo: PPropInfo;
begin
  PropInfo := GetPropInfo(Sender, 'Text', []);
  if Assigned(PropInfo) then
    SetStrProp(Sender, PropInfo, '');
end;

In some cases, some controls use Text and some use Caption instead, eg;

function TForm1.ControlClick(Sender: TObject);
var
  PropInfo: PPropInfo;
begin
  PropInfo := GetPropInfo(Sender, 'Text', []);
  if not Assigned(PropInfo) then
    PropInfo := GetPropInfo(Sender, 'Caption', []);
  if Assigned(PropInfo) then
    SetStrProp(Sender, PropInfo, '');
end;