【发布时间】:2014-10-25 23:51:50
【问题描述】:
我正在尝试将接口指针存储在TTreeNode.Data 属性下的树视图中。虽然我能够存储一个接口指针 (Node.Data := Pointer(MyInterface);),但它似乎并不能以相反的方式工作 (MyInterface := ISomeInterface(Node.Data);)。它总是出现nil。
我还尝试使用手动引用计数,正如我在another question 中看到的那样。但是,它仍然出现 nil 并且现在出现内存泄漏。
//Clears tree view and adds drive letters
procedure TfrmMain.cmdRefreshBrowseClick(Sender: TObject);
var
Arr, O: ISuperObject;
X: Integer;
N, C: TTreeNode;
begin
//First clear all items and release their interface refs
for N in tvBrowse.Items do begin
O:= ISuperObject(N.Data);
O._Release;
end;
tvBrowse.Items.Clear;
Arr:= ListDirectory(''); //Returns ISuperObject array listing drives
for X := 0 to Arr.AsArray.Length-1 do begin
O:= Arr.AsArray.O[X];
N:= tvBrowse.Items.Add(nil, O.S['drive']+':\ ['+O.S['type']+']'); //Add root node
N.Data:= Pointer(O); // Assign interface pointer to node data
O._AddRef; //Manually increment interface reference count
C:= tvBrowse.Items.AddChild(N, ''); //Add a fake child node
end;
end;
procedure TfrmMain.tvBrowseExpanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean);
var
N, C: TTreeNode;
P, A, O: ISuperObject;
X: Integer;
begin
//Check first node if it's a fake node
N:= Node.getFirstChild;
if N.Text = '' then begin //if first node is a fake node...
P:= ISuperObject(Node.Data); // <-- P always comes out nil here???
N.Delete; //Delete first "fake" node
//Get child files/folders
if Node.Parent = nil then //If root (drive) node...
A:= ListDirectory(P.S['drive']+':\') //Returns ISuperObject array listing files/folders
else
A:= ListDirectory(P.S['name']); //Returns ISuperObject array listing files/folders
for X := 0 to A.AsArray.Length-1 do begin
O:= A.AsArray.O[X];
C:= tvBrowse.Items.AddChild(N, O.S['name']); //Add child node
C.Data:= Pointer(O); //Assign interface pointer to node data
O._AddRef; //Manually increment reference count
end;
end;
end;
这样做的适当方法是什么?
【问题讨论】:
-
你可以研究TInterfaceList的代码。
-
或者我可以将每个接口及其内容转换为记录并存储记录指针而不是接口指针
-
如果你放一个InterfaceList,你的TTreeNode.Data指向InterfaceItem?树视图中的每一项都是 interfacelist 中的一项。