@@ -621,7 +621,7 @@ TVTReference = record
621621 function GetData(): Pointer; overload; inline;
622622 function GetData<T>(): T; overload; inline;
623623 procedure SetData(pUserData: Pointer); overload;
624- procedure SetData<T:class >(pUserData: T); overload;
624+ procedure SetData<T>(pUserData: T); overload;
625625 procedure SetData(const pUserData: IInterface); overload;
626626 end;
627627
@@ -3028,7 +3028,7 @@ TBaseVirtualTree = class(TCustomControl)
30283028 procedure SetCheckStateForAll(aCheckState: TCheckState; pSelectedOnly: Boolean);
30293029 procedure SetNodeData(pNode: PVirtualNode; pUserData: Pointer); overload; inline;
30303030 procedure SetNodeData(pNode: PVirtualNode; const pUserData: IInterface); overload; inline;
3031- procedure SetNodeData<T:class >(pNode: PVirtualNode; pUserData: T); overload;
3031+ procedure SetNodeData<T>(pNode: PVirtualNode; pUserData: T); overload;
30323032 procedure Sort(Node: PVirtualNode; Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); virtual;
30333033 procedure SortTree(Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); virtual;
30343034 procedure ToggleNode(Node: PVirtualNode);
@@ -14779,7 +14779,7 @@ procedure TBaseVirtualTree.SetFiltered(Node: PVirtualNode; Value: Boolean);
1477914779 Include(Node.States, vsFiltered);
1478014780 if not (toShowFilteredNodes in FOptions.FPaintOptions) then
1478114781 begin
14782- if vsInitializing in Node.States then
14782+ if ( vsInitializing in Node.States) and not (vsHasChildren in Node.States) then
1478314783 AdjustTotalHeight(Node, 0, False)
1478414784 else
1478514785 AdjustTotalHeight(Node, -Integer(NodeHeight[Node]), True);
@@ -14958,7 +14958,7 @@ procedure TBaseVirtualTree.SetNodeData<T>(pNode: PVirtualNode; pUserData: T);
1495814958 // Can be used to set user data of a PVirtualNode to a class instance.
1495914959
1496014960begin
14961- SetNodeData( pNode, Pointer (pUserData) );
14961+ pNode.SetData<T> (pUserData);
1496214962end;
1496314963
1496414964procedure TBaseVirtualTree.SetNodeData(pNode: PVirtualNode; const pUserData: IInterface);
@@ -19889,6 +19889,8 @@ procedure TBaseVirtualTree.DoFocusNode(Node: PVirtualNode; Ask: Boolean);
1988919889
1989019890procedure TBaseVirtualTree.DoFreeNode(Node: PVirtualNode);
1989119891
19892+ var
19893+ IntfData: IInterface;
1989219894begin
1989319895 // Prevent invalid references
1989419896 if Node = FLastChangedNode then
@@ -19908,7 +19910,12 @@ procedure TBaseVirtualTree.DoFreeNode(Node: PVirtualNode);
1990819910 FOnFreeNode(Self, Node);
1990919911
1991019912 if vsReleaseCallOnUserDataRequired in Node.States then
19911- GetInterfaceFromNodeData<IInterface>(Node)._Release();
19913+ begin
19914+ // Data may have been set to nil, in which case we can't call _Release on it
19915+ IntfData := GetInterfaceFromNodeData<IInterface>(Node);
19916+ if Assigned(IntfData) then
19917+ IntfData._Release();
19918+ end;
1991219919
1991319920 FreeMem(Node);
1991419921 if Self.UpdateCount = 0 then
@@ -34478,7 +34485,13 @@ procedure TVirtualNode.SetData(const pUserData: IInterface);
3447834485procedure TVirtualNode.SetData<T>(pUserData: T);
3447934486
3448034487begin
34481- SetData(Pointer(pUserData));
34488+ T(Pointer((PByte(@(Self.Data))))^) := pUserData;
34489+ case PTypeInfo(TypeInfo(T)).Kind of
34490+ tkClass:
34491+ Include(Self.States, vsOnFreeNodeCallRequired);
34492+ tkInterface:
34493+ Include(Self.States, vsReleaseCallOnUserDataRequired);
34494+ end;
3448234495end;
3448334496
3448434497{ TVTImageInfo }
0 commit comments