Search code examples
delphidelphi-7

TList descendant with another otbject?


I need to impliment a TList descendant of controls + an extra object.
something like:

List.Add(AControl, AObject)

So The List will hold both AControl, AObject

What is the best way of doing this with Delphi 7?


Solution

  • You can store a list of records, then you can put whatever you want into the record, eg:

    type
      PMyRecord = ^MyRecord;
      MyRecord = record
        Control: TControl;
        Object: TObject;
      end;
    
    var
      Rec: PMyRecord;
    begin
      New(Rec);
      try
        Rec.Control := AControl;
        Rec.Object := AObject;
        List.Add(Rec);
      except
        Dispose(Rec);
        Raise;
      end;
    end;
    

    var
      Rec: PMyRecord;
    begin
      Rec := PMyRecord(List[SomeIndex]);
      // use Rec.Control and Rec.Object as needed...
    end;
    

    Don't forget to Dispose() an item when you remove it from the list:

    var
      Rec: PMyRecord;
    begin
      Rec := PMyRecord(List[SomeIndex]);
      List.Delete(SomeIndex);
      Dispose(Rec);
    end;
    

    And also when you are finished using the list, or at least when you Clear() it:

    var
      I: Integer;
      Rec: PMyRecord;
    begin
      for I := o to List.Count-1 do
        Dispose(PMyRecord(List[I]));
      //...
    end;
    

    If you derive a new class from TList, you can override its virtual Notify() method to dispose items:

    type
      TMyList = class(TList)
      protected
        function Get(Index: Integer): PMyRecord;
        procedure Notify(Ptr: Pointer; Action: TListNotification); override;
      public
        function Add(AControl: TControl; AObject: TObject): Integer;
        procedure Insert(Index: Integer; AControl: TControl; AObject: TObject);
        property Items[Index: Integer]: PMyRecord read Get; default;
      end;
    
    function TMyList.Add(AControl: TControl; AObject: TObject): Integer;
    var
      Rec: PMyRecord;
    begin
      New(Rec);
      try
        Rec.Control := AControl;
        Rec.Object := AObject;
        Result := inherited Add(Rec);
      except
        Dispose(Rec);
        Raise;
      end;
    end;
    
    procedure TMyList.Insert(Index: Integer; AControl: TControl; AObject: TObject);
    var
      Rec: PMyRecord;
    begin
      New(Rec);
      try
        Rec.Control := AControl;
        Rec.Object := AObject;
        inherited Insert(Index, Rec);
      except
        Dispose(Rec);
        Raise;
      end;
    end;
    
    function TMyList.Get(Index: Integer): PMyRecord;
    begin
      Result := PMyRecord(inherited Get(Index));
    end;
    
    procedure TMyList.Notify(Ptr: Pointer; Action: TListNotification);
    begin
      inherited;
      if Action = lnDeleted then
        Dispose(PMyRecord(Ptr));
    end;