Rather than using a separate class in the TListItem.Data property, it would be safer and more efficient to derive a new class from TListItem and add whatever members you want to it, and then return that class type from the ListView's OnCreateItemClass event. You can then type-cast any TListItem in the ListView to your custom class type when needed, and you don't have to worry about freeing them manually. For example:
type
TMyListItem = class(TListItem)
public
BoldText: Boolean;
end;
procedure TForm8.ListView1CreateItemClass(Sender: TCustomListView;
var ItemClass: TListItemClass);
begin
ItemClass := TMyListItem;
end;
procedure TForm8.ListView1AdvancedCustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Integer; State: TCustomDrawState;
Stage: TCustomDrawStage; var DefaultDraw: Boolean);
begin
if TMyListItem(Item).BoldText then
Sender.Canvas.Font.Style := [fsBold];
end;
...
var li := ListView1.Items.Add;
TMyListItem(li).BoldText := True;
Of course, in this particular example, there is a much simpler solution - just look at the data being drawn and act accordingly, eg:
procedure TForm8.ListView1AdvancedCustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Integer; State: TCustomDrawState;
Stage: TCustomDrawStage; var DefaultDraw: Boolean);
begin
if (SubItem > 0) and (StrToInt(Item.SubItems[SubItem-1]) < 0) then
Sender.Canvas.Font.Style := [fsBold];
end;