treeview,listview协同作战(100分)

  • 主题发起人 主题发起人 xuhuizhe
  • 开始时间 开始时间
X

xuhuizhe

Unregistered / Unconfirmed
GUEST, unregistred user!
各位高人:
本人在学习使用treeview和listview协同作战:
左边使用treeview,右边使用listview,
目标:点击treeview的任一选项,listview中出现该选项的一级子项
过程:参阅demos中的Resxplor例子
程序编绎成功,运行时弹出错误提示:
Accss violation ataddress 0044E501 in module 'rightmain.exe',Read of address 00000000
请教如何解决这一问题????最好能列出程序

程序清单如下:
unit main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExeImage,StdCtrls,Buttons,ExtCtrls,ComCtrls, Menus,RXMisc, HexDump,
ImgList;

type
Tright = class(TForm)
ScrollBox1: TScrollBox;
TreeView1: TTreeView;
ScrollBox2: TScrollBox;
ListView1: TListView;
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
N8: TMenuItem;
N9: TMenuItem;
N10: TMenuItem;
procedure N7Click(Sender: TObject);
procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
private
procedure UpdatelistView(Reslist:TResourcelist);
{ Private declarations }
public
{ Public declarations }
end;

var
right: Tright;

implementation
uses About, RXTypes;
{$R *.DFM}

procedure Tright.N7Click(Sender: TObject);
begin
close;
end;

procedure Tright.TreeView1Change(Sender: TObject; Node: TTreeNode);
var I:integer;R:TResourceItem;
begin
with treeview1 do
begin
if assigned(selected) then
begin
R:=tresourceitem(selected.Data);
if R.IsList then updatelistview(R.list);
end;
end;
end;

procedure Tright.UpdatelistView(Reslist:TResourcelist);
var I:integer;
begin
ListView1.items.clear;
for I := 0 to ResList.Count-1 do
with ResList, ListView1.Items.Add do
begin
Data := ResList;
Caption := Name;
end;
end;

end.

 
其中就是
if R.IsList then updatelistview(R.list);
这句有问题,而且是调用r.islist是出的把r.islist屏蔽之后,r.list也出同样问题,
但是找不到原因,

恳请协助,谢谢!!!
 
首先判断一下R是不是Nil
一步一步调试,看看到底什么错误,应该不难的
 
我是在treeview的items属性中设置:
系统设置
---群组管理
---群组
---成员
---部门管理
---财务
---业务
---采购
---仓库
我的目的是:
单击<系统设置>,右边listview中出现<群组管理>,<部门管理>
单击<群组管理>,右边listview中出现<群组>,<成员>
类推.

我在demos中的Resxplor例子的treeview的items属性中进行相同设置,也出现同样错误,
可能我的整个思路是错误的,烦请哪位高人提供源码实现这种功能,用其它控件实现亦可.

谢谢!
 
>>selected.Data
if data 为 point then Strings(selected.Data^)

 
留下你的mail,我给你发个详细的例子.
 
xuhuizhe@21cn.com
xuhuizhe@sina.com
 
请发21cn的,sina的有点问题,刚才收上一份既无主题内容,又无附件的email,
发信人yzzep@sina.com,不知是不是sword_liu先生发的
 
如果猜的不错,R:=tresourceitem(selected.Data);中的tresourceitem应该是其他单元
定义的结构,你在这里有个错误:应该是R:=tresourceitem(selected.Data^),另外,
记住了,在退出程序或treeview.items.clear前应该先dispose掉data。
 
不是这样,前面那位kunmeng老兄也谈到了,可是我试了改成
R:=tresourceitem(selected.Data^)
错误依然如故,不信请在demos中的Resxplor例子的treeview的items属性中进行相同设置,
即会出现同样错误提示, 在线等到现在,身心俱损,万望给出源码,得以解脱[red][/red][:(]
 
TResourcelist和tresourceitem是什么?是自定义结构吧?
你程序中可能的漏洞:
procedure Tright.UpdatelistView(Reslist:TResourcelist);
var I:integer;
begin
ListView1.items.clear; //从后面的程序看,Data中应该有指向的地址,clear而
//不dispose掉data指向的内存,程序退出时会出错,
//程序运行中也可能会出错
for I := 0 to ResList.Count-1 do
with ResList, ListView1.Items.Add do
begin
Data := ResList; //这里赋值,如果ResList在其它处被释放,
//再引用这个值就会出错
Caption := Name;
end;
end;

还有,在你给出的代码中,没有看到为TreeNode的data赋值的语句,没有赋值的当然要
出错,也许是代码不完整,这些代码也只能这样分析了!
 
[gold][/gold]楼上这位老兄也许分析得很对,可是我没到目前没到这个层次,
去引用内存指针等等;

现在我是想设计期间在treeview的items中设置树,在运行期间单击treeview中的项目,
在listview中显示该项目的一级子项目而已,就象windows的资源管理器那样;

只不过是看到delphi自带的demos中有个Resxplor例子比较相似,所以就往上套,
现在看来是错误的;

请各位大侠公布一些简单范例,或发至:xuhuizhe@21cn.com
 
var
i : Integer;
{$R *.DFM}

procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
i := 0;
ListView1.Items.Clear;
GetAllSubNode(TreeView1.Selected);
end;

procedure TForm1.GetAllSubNode(SelNode: TTreeNode);
var
TN : TTreeNode;
ListItem: TListItem;
begin
if i <> 0 then
begin
ListItem := ListView1.Items.Add;
ListItem.Caption := SelNode.Text;
end;

if SelNode.HasChildren then
begin
I := i + 1;
TN := SelNode.getFirstChild;
GetAllSubNode(TN);
TN := TN.getNextSibling;
while TN <> nil do
begin
GetAllSubNode(TN);
TN := TN.getNextSibling;
end;
end;
end;
 
问题所在:你在初式花treeview的时候,对node 的data属性 没有赋值,
所以取不到selected.Data的值。
 
dirk分析程序辛苦了可惜没理解我提问的目标, sword_liu发来的程序是另一个网站下载到的,我早已看过,
但没能解决问题,svw0506大侠写得不错尤其是用递归算法对树进行遍历,非常欣赏,深表钦佩,我需的结果只是
一级子目录,将svw0506的程序稍作修改结贴
procedure Tright.GetAllSubNode(SelNode: TTreeNode);
var
TN : TTreeNode;
ListItem: TListItem;
begin
if SelNode.HasChildren then
begin
I := i + 1;
TN := SelNode.getFirstChild;
ListItem := ListView1.Items.Add;
ListItem.Caption := TN.Text;
TN := TN.getNextSibling;
while TN <> nil do
begin
ListItem := ListView1.Items.Add;
ListItem.Caption := TN.Text;
TN := TN.getNextSibling;
end;
end;
end;
 
问:xuhuizhe

你的问题解决了,可是如果,
系统设置
---群组管理
---群组
---成员
---部门管理
---财务
---业务
---采购
---仓库
点击treeview的系统设置,则在listview显示群组管理、部门管理,如果此时点击
listview里面群组管理可以在listview里面显示其下级节点群组、成员么?
如果再点击,成员,可以打开相应的窗体么?这该如何实现啊。
 
后退
顶部