Hola a todos,
Hace algún tiempo descubrí los HELPER como una posibilidad muy interesante que incluye el lenguaje PASCAL, aunque realmente no se en que momento se introdujo en el lenguaje.
Básicamente lo que permite es añadirle funcionalidades que no existen o que podamos necesitar, a classes u otras estructuras de datos, con la ventaja de que se puede utilizar directamente sin necesidad de modificar nada de lo que ya hay creado por debajo. No necesita llamar a create/destroy, ni hacer nada especial con lo que ya hay creado o funcionando.
Tiene algunas limitaciones como no poder utilizar nuevas estructuras de datos dentro del propio HELPER, siempre y cuando sean necesarias crearlas junto con el propio componente, por la imposibilidad de sobreescribir los procedimientos constructor/destructor del método original sobre el que se aplica el HELPER y porque si no esta incluida nuestra nueva unidad con el HELPER en el resto de código entonces todas las modificaciones existentes es como si no existieran.
Como ejemplo simple pero bastante interesante es el típico código para insertar un ProgressBar a un LISTITEM de un LISTVIEW y aquí como quedaría insertado como un HELPER de un LISTITEM en una unidad independiente:
Código Delphi
[-]
unit ListItemHelpers;
interface
uses Windows, ComCtrls;
type
TListItemHelper = class helper for TListItem
private
function GetRect(AColumn: Integer): TRect;
function GetProgressBar: TProgressBar;
public
procedure AdjustProgressBar;
function AddPRogressBar(AColumn: integer = 1): TProgressBar;
procedure DeleteProgressBar;
property ProgressBar: TProgressBar read GetProgressBar;
end;
implementation
uses
Dialogs, System.SysUtils;
procedure Error(E:Exception; const msgTxt:String);
begin
MessageDlg(E.Message + #13 + msgTxt, mtError, [mbOK], 0);
end;
function TListItemHelper.AddPRogressBar(AColumn: integer): TProgressBar;
begin
if assigned(Data) then begin
Result := data;
exit;
end;
result := TProgressBar.Create(ListView);
result.parent := ListView;
result.DoubleBuffered := true;
if (AColumn <= 0) then
AColumn := 1;
result.Tag := AColumn;
Data := result;
AdjustProgressBar;
end;
procedure TListItemHelper.AdjustProgressBar;
var
pb: TProgressBar;
begin
pb := Data; if assigned(pb) then
pb.BoundsRect := GetRect(pb.Tag);
end;
procedure TListItemHelper.DeleteProgressBar;
var
pb: TProgressBar;
begin
try
pb := Data;
if assigned(pb) then
try
freeAndNil(pb);
data := Nil;
except
on E: Exception do
error(e, 'TListItemHelper.DeleteProgressBar');
end;
except
on E: Exception do
error(E, 'TListItemHelper.DeleteProgressBar');
end;
end;
function TListItemHelper.GetProgressBar: TProgressBar;
begin
try
Result := nil;
if not Assigned(Data) then
AddPRogressBar;
result := TObject(Data) as TProgressBar
except
on E: Exception do
Error(E, 'TListItemHelper.GetProgressBar');
end;
end;
function TListItemHelper.GetRect(AColumn: Integer): TRect;
var
i: longint;
begin
result := DisplayRect(drBounds);
with TListView(ListView) do begin
if AColumn = 0 then
AColumn := columns.Count - 1;
for i := 1 to AColumn do
result.left := result.left + columns[i - 1].Width;
result.right := result.Left + columns[AColumn].Width;
end;
end;
end.
Para usarlo solamente es necesario añadir la unidad con el HELPER a nuestro formulario y listo, tendremos las nuevas funciones disponibles para su uso:
Código Delphi
[-]
uses ..., ListItemHelpers;
...
procedure TForm1.AddProgressBarClick(Sender: TObject);
begin
ListView1.Selected.addProgressBar;
end;
procedure TForm1.DeleteProgressBarClick(Sender: TObject);
begin
ListView1.Selected.DeleteProgressBar;
end;
procedure TForm1.DeleteItemClick(Sender: TObject);
begin
ListView1.selected.DeleteProgressBar;
ListView1.DeleteSelected;
end;
procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
Item.AdjustProgressBar;
end;
Esta técnica sobre todo la veo interesante por su simplicidad de uso,
Espero les sea util
Un saludo