Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: How does TSubItems->Assign() work?


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 1 - Last Post: Oct 13, 2015 3:05 PM Last Post By: Remy Lebeau (Te...
Igor Marchenko

Posts: 43
Registered: 4/1/11
How does TSubItems->Assign() work?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 13, 2015 1:56 PM
When working with the ListView Items editor I add one item "A1" and add two subitems "S1" and "S2" to item "A1".
When I click Apply data is saved. I was wondering what the code is executed. I opened the c:\Program Files (x86)\Embarcadero\Studio\15.0\source\Property Editors\ItemEdit.pas and found the following code:
procedure TListViewItems.ApplyClick(Sender: TObject);
var
  Node: TTreeNode;
  ListItem: TListItem;
begin
  FlushControls;
  Items.Clear;
  if TreeView.Items.Count > 0 then Node := TreeView.Items[0]
  else Node := nil;
  while Node <> nil do
  begin
    if Node.Data <> nil then
    begin
      ListItem := Items.Add;
      GetItem(TItemInfo(Node.Data), ListItem);
      Node := Node.GetNextSibling;
    end
  end;
  with TListView(Items.Owner) do UpdateItems(0, Items.Count -1);
  Apply.Enabled := False;
end;

and GetItem method:
procedure TListViewItems.GetItem(ItemInfo: TItemInfo; Value: TListItem);
var
  I: Integer;
begin
  with Value do
  begin
    Caption := ItemInfo.FCaption;
    ImageIndex := ItemInfo.FImageIndex;
    StateIndex := ItemInfo.FStateIndex;
    GroupID := ItemInfo.FGroupID;
    SubItems.Assign(ItemInfo.FSubItems);
    for I := 0 to ItemInfo.FSubItems.Count - 1 do
      SubItemImages[I] := Integer(ItemInfo.FSubItemImages[I]);
  end;
end;

Here we can see that item member SubItems assigns ItemInfo.FSubItems. It's clear. But I do not understand where is invoked the Add method of SubItems? I opened Vcl.ComCtrls.pas file and found declaration of TSubItems class (line 16148). And there is no overriding of the Assign method.
So my question is - when occurs adding subitems to ListView when we click "Apply" button of the *Items editor*? I need to know it because I want to use this mechanism in my component.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How does TSubItems->Assign() work?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 13, 2015 3:05 PM   in response to: Igor Marchenko in response to: Igor Marchenko
Igor wrote:

Here we can see that item member SubItems assigns ItemInfo.FSubItems.
It's clear. But I do not understand where is invoked the Add method of
SubItems?

TSubItems is a TStringList descendant. The TStrings and TStringList classes
implement the Assign() method (see $(BDS)\source\rtl\common\System.Classes.pas):

procedure TStrings.Assign(Source: TPersistent);
begin
  if Source is TStrings then
  begin
    BeginUpdate;
    try
      Clear;
      ...
      AddStrings(TStrings(Source));
    finally
      EndUpdate;
    end;
    Exit;
  end;
  inherited Assign(Source);
end;
 
procedure TStrings.AddStrings(Strings: TStrings);
var
  I: Integer;
begin
  BeginUpdate;
  try
    for I := 0 to Strings.Count - 1 do
      AddObject(Strings[I], Strings.Objects[I]);
  finally
    EndUpdate;
  end;
end;
 
function TStringList.AddObject(const S: string; AObject: TObject): Integer;
begin
  if not Sorted then
    Result := FCount
  else
    if Find(S, Result) then
      case Duplicates of
        dupIgnore: Exit;
        dupError: Error(@SDuplicateString, 0);
      end;
  InsertItem(Result, S, AObject);
end;
 
procedure TStringList.Assign(Source: TPersistent);
begin
  inherited Assign(Source);
  if Source is TStringList then
  begin
    ...
  end;
end;


The TSubItems class overrides the AddObject() method:

function TSubItems.AddObject(const S: string; AObject: TObject): Integer;
begin
  Result := inherited AddObject(S, AObject);
{$IFDEF CLR}
  FImageIndices.Add(TObject(TImageIndex(-1)));
{$ELSE}
  FImageIndices.Add(Pointer(-1));
{$ENDIF}
  RefreshItem(Result + 1);
end;


I opened Vcl.ComCtrls.pas file and found declaration of TSubItems
class (line 16148). And there is no overriding of the Assign method.

Because the default implementations in TStrings and TStringList are sufficient,
so Assign() does not need to be overriden by TSubItems. It overrides AddObject()
instead, which Assign() calls internally.

So my question is - when occurs adding subitems to ListView when
we click "Apply" button of the *Items editor*?

When Assign() is called.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02