TreeNode的data使用问题(100分)

  • 主题发起人 主题发起人 lizheng
  • 开始时间 开始时间
L

lizheng

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure TMainForm.InterLoadFiles;
var
RootNode, CDNode : TTreeNode;
CDName,UpPath : string;

Procedure Add(UpNode:TTreeNode;UpPath:String);
Var
FileNode:TTreeNode;
Path:String;
Begin
With FileDataModule Do
Begin
If UpPath<>'*' Then
FileTable.Filter:=Format('光盘名称=''%s'' AND 所属文件夹=''%s'' AND 文件类型=''文件夹''', [CDName,UpPath]);
FileTable.First;
While Not FileTable.EOF Do
Begin
Path := FileDataModule.FileTable[ '所属文件夹' ] ;
FileNode := TreeView.Items.AddChildObject( UpNode,
FileDataModule.FileTable[ '文件名称' ],
Pointer(Path));
ShowMessage(Path);
ShowMessage(String(FileNode.Data));
     ~~~~~~~~~~~~~~~~~此处没有问题,但下面就出现问题了。
FileNode.ImageIndex:=1;
FileNode.SelectedIndex := 2;
UpPath:=FileTable['所属文件夹']+FileTable['文件名称']+'/';
Add(FileNode,UpPath);
FileTable.Next;
End;
End;
End;

begin
With FileDataModule Do
Try
Begin
FileTable.DisableControls;
FileTable.Filtered:=TRUE;
TreeView.Items.Clear;
RootNode := TreeView.Items.Add( nil, 'Favorite' );
RootNode.ImageIndex := 0;
CDTable.Open;
FileTable.Open;
FileCDTable.Open;
CDNOTable.Open;
CDTable.First;
while not CDTable.EOF do
begin
CDName :=CDTable['光盘名称'];
CDNode := TreeView.Items.AddChild( RootNode, CDName );
CDNode.ImageIndex := 1;
CDNode.SelectedIndex := 2;
FileTable.Filter := Format( '光盘名称 = ''%s''', [ CDName ] );
UpPath:='*';
Add(CDNode,UpPath);
CDTable.Next;
end;
FileTable.Filter := '';
FileTable.Filtered:=FALSE;
FileTable.EnableControls;
RootNode.Expand( False );
RootNode.Selected := True;
End;
Finally
FileTable.Close;
CDTable.Close;
End;
end;

procedure TMainForm.TreeViewChange(Sender: TObject; Node: TTreeNode);
var
I : Integer;
ListItem : TListItem;
Path:String;
begin
if (Node.Level=nlRoot) OR (Node.Level=nlCD) then
begin
ListView.Items.BeginUpdate;
try
ListView.Items.Clear;
for I := 0 to Node.Count - 1 do
begin
ListItem := ListView.Items.Add;
ListItem.Caption := Node.Item[ I ].Text;
ListItem.ImageIndex := 1
end;
finally
ListView.Items.EndUpdate;
End;
End
else
Begin
ListView.Items.BeginUpdate;
Try
ListView.Items.Clear;
for I := 0 to Node.Count - 1 do
begin
ListItem := ListView.Items.Add;
ListItem.Caption :=Node.Item[ I ].Text;
ListItem.ImageIndex := 1
end;
// ShowMessage(String(Node.Data));
Path := String(Node.Data);
~~~此处的Path值乱七八糟'#0#.....'不知为什么?
Path :=Path+Node.Text+'/';
With FileDataModule.FileTable Do
Begin
Open;
First;
Filter:=Format('所属文件夹=''%s'' AND 文件类型<>''文件夹''', [Path]);
~~~~
{ 错误:Project Project1.exe raised excption class EDatabaseError with
message 'Unterminated string constant'.Process stopped.Use Step
or Run to continue.
}






While Not Eof Do
Begin
if FieldByName('文件类型').AsString<>'文件夹' then
Begin
ListItem := ListView.Items.Add;
ListItem.Caption := FieldByName('文件名称').AsString;
ListItem.ImageIndex := 3;
End;
FileDataModule.FileTable.Next;
End;
Close;
End;
finally
ListView.Items.EndUpdate;
End;
End;
end;

end.
 
nlRoot=0
nlCD=1
 
TTreeNode的data是一个指针,你直接String(Node.Data)恐怕不合适,
不过没看到你的data是怎么赋值的,所以不好说.

最好还是用pchar来操作吧!或者试一试这个:
Path := StrPas(pchar(Node.Data));
 
//不过没看到你的data是怎么赋值的,所以不好说.
就在procedure TMainForm.InterLoadFiles的子过程Add里面啊。
~~~~~~~~~~~~~~~~~最开头。
 
FileNode := TreeView.Items.AddChildObject( UpNode,
FileDataModule.FileTable[ '文件名称' ], Pointer(Path));
~~~~~~~~~~~~~改为@Path

Path := String(Node.Data);
~~~~~~~~~~~~~~~~~改为 String((Node.Data)^)

试试看! Good luck!
 
我会试试看的,
但程序中前面的ShowMessage(String(FileNode.Data))为什么没有错。

type
{ PPath = ^TPath;
TPath = record
Path: string;
end;
}
...
...

Const
pgCD = 0; { Page index values }
pgImageContent = 1;
pgTextContent = 2;
pgHtmlContent = 3;

nlRoot = 0; { Node level values }
nlCD = 1;

procedure TMainForm.InterLoadFiles;
var
RootNode, CDNode : TTreeNode;
CDName,UpPath : string;

Procedure Add(UpNode:TTreeNode;UpPath:String);
Var
FileNode:TTreeNode;
//Path:String;
Path:PString;
Begin
With FileDataModule Do
Begin
If UpPath<>'*' Then
FileTable.Filter:=Format('光盘名称=''%s'' AND 所属文件夹=''%s'' AND 文件类型=''文件夹''', [CDName,UpPath]);
FileTable.First;
While Not FileTable.EOF Do
Begin
New(Path);
Path^ := (FileDataModule.FileTable[ '所属文件夹' ]) ;
FileNode := TreeView.Items.AddChildObject( UpNode,
FileDataModule.FileTable[ '文件名称' ],
Path);
FileNode.ImageIndex:=1;
FileNode.SelectedIndex := 2;
UpPath:=FileTable['所属文件夹']+FileTable['文件名称']+'/';
//UpPath是上一级目录带后面的'/'
Add(FileNode,UpPath);
FileTable.Next;
End;
End;
End;

begin
With FileDataModule Do
Try
Begin
FileTable.DisableControls;
FileTable.Filtered:=TRUE;
TreeView.Items.Clear;
RootNode := TreeView.Items.Add( nil, 'Favorite' );
RootNode.ImageIndex := 0;
CDTable.First;
while not CDTable.EOF do
begin
CDName :=CDTable['光盘名称'];
CDNode := TreeView.Items.AddChild( RootNode, CDName );
CDNode.ImageIndex := 1;
CDNode.SelectedIndex := 2;
FileTable.Filter := Format( '光盘名称 = ''%s''', [ CDName ] );
UpPath:='*';
Add(CDNode,UpPath);
CDTable.Next;
end;
FileTable.Filter := '';
FileTable.Filtered:=FALSE;
FileTable.EnableControls;
RootNode.Expand( False );
RootNode.Selected := True;
End;
Except
......
End;
end;

procedure TMainForm.TreeViewChange(Sender: TObject; Node: TTreeNode);
var
I : Integer;
ListItem : TListItem;
Path:PString;
begin
if (Node.Level=nlRoot) OR (Node.Level=nlCD) then
begin
ListView.Items.BeginUpdate;
try
ListView.Items.Clear;
for I := 0 to Node.Count - 1 do
begin
ListItem := ListView.Items.Add;
ListItem.Caption := Node.Item[ I ].Text;
ListItem.ImageIndex := 1
end;
finally
ListView.Items.EndUpdate;
End;
End
else
Begin
ListView.Items.BeginUpdate;
Try
ListView.Items.Clear;
for I := 0 to Node.Count - 1 do
begin
ListItem := ListView.Items.Add;
ListItem.Caption :=Node.Item[ I ].Text;
ListItem.ImageIndex := 1
end;
New(Path);
Path^ := PString(Node.Data)^+Node.Text+'/';
With FileDataModule.FileTable Do
Begin
First;
Filter:=Format('所属文件夹=''%s'' AND 文件类型<>''文件夹''', [Path^]);
Filtered:=TRUE;
While Not Eof Do
Begin
ListItem := ListView.Items.Add;
ListItem.Caption := FieldByName('文件名称').AsString;
ListItem.ImageIndex := 3;
FileDataModule.FileTable.Next;
End;
Filtered:=FALSE;
End;
finally
ListView.Items.EndUpdate;
End;
End;
end;


end.


改为PString或者用记录类型好了,Why?
 
so easy.
string由delphi管理. pstring, pchar是指针(甚至可以认为是无类型4字节长
的数据)
你的path是procedure ....中的局部变量. 如果定义为string. 将由delphi管理
它的内存分配与释放(不幸的是, 当你退出你的procedure时, delphi将它释
放掉了).
如果定义成pstring或者pchar, 退出procedure时, delphi释放掉的只是4字节
长的一块内存(指针占用的空间). 具体存放数据是由你显式分配的(在堆栈
中), 释放也要由你显式释放. delphi管不着. 所以退出你的procedure时, 具体
存放数据的内存块没有被释放掉, 还能被其他过程使用, 直到你显式释放
这块内存为止(如果你不释放, 这就是所谓内存泄露的由来).
 
To Another_eYes:
还有一个问题,如果我把Patn定义成Integer类型,
Path := FileDataModule.FileTable[ '文件编号' ] ;
FileNode := TreeView.Items.AddChildObject( UpNode,
FileDataModule.FileTable[ '文件名称' ],
Pointer(Path));
在后面的procedure TMainForm.TreeViewChange(Sender: TObject; Node: TTreeNode);
中用Path := Integer(Node.Data)就没有问题,为什么?
 
上来一次好不容易,还是现把分分了吧。
 
后退
顶部