You need to capture the value of the interface reference rather than the address of the variable that holds the reference.
So, do it like this:
Node.Data := Pointer(X);
....
X := IInterface(Node.Data);
// use IInterface in preference to IUnknown
But you must make sure that you handle the reference counting properly since this cast subverts automatic reference counting.
So, take a reference when you put the interface into the Node:
Node.Data := Pointer(X);
X._AddRef;
and call _Release
whenever you modify Node.Data
, or destroy the node.
This is rather messy, and easy to get wrong, as you found out. A better way to solve the problem is to let the compiler do the work. Define a sub-class of TTreeNode
, and make your tree view use that sub-class. Ignore the Data property of the node and use your own property of type IInterface
, introduced in the sub-class.
The way to make this happen is to supply an OnCreateNodeClass
event handler that tells the tree view control to create nodes of your sub-class rather than plain old TTreeNode
. And example of that technique can be found here: https://stackoverflow.com/a/25611921/