我动态把这份XML文档生成一到TREEVIEW中 把其中一个属性附到 treeview 的 node.data 中结果 指针错乱了。。我断点跟跟踪进去确实有发现值有写进去啊。。为什么这么奇怪?
请教各位程序有点长。。我为了保持完 整性谢谢大家帮助了出现的问题是 指针老是指到下一个节点的值去了。。好奇怪
这份文档的格式是 1.xml
<?xml version="1.0" encoding="GB2312"?>
<INSTITUTION NAME="机构名">
<DEPARTMENT NAME="部门一">
<APPLICATION NAME="程序名1" TYPE="类型1" LINK="111111111111" ICON="图标1"/>
</DEPARTMENT>
<DEPARTMENT NAME="部门二">
<APPLICATION NAME="程序名2" TYPE="类型2" LINK="2222222222222" ICON="图标2"/>
</DEPARTMENT>
<DEPARTMENT NAME="部门三">
<APPLICATION NAME="程序名3" TYPE="类型3" LINK="333333333333" ICON="图标3"/>
</DEPARTMENT></INSTITUTION>//---------------------------------------------------------
//TO DO :  添加树的子节点
//参数 :   树的节点TEXT 当前node 父级nodes
//返回 : 返回一个树node 对象
function TMainForm.AddChildNode(text,value:string;node:TTreeNode;ParentNode:TTreeNodes):TTreeNode;
var
 nodes:TTreeNode;
begin
  nodes:=ParentNode.AddChildObject(node,text,nil);
  nodes.Data:=pchar(value);
  Result:=nodes;
end;
//---------------------------------------------------------//---------------------------------------------------------
//TO DO :  添加树的根节点
//参数 :   树的节点TEXT 父级nodes
//返回 : 返回一个树node 对象
function TMainForm.AddNode(text:string;ParentNode:TTreeNodes):TTreeNode;
var
  node:TTreeNode;
begin
  node:=ParentNode.Add(nil,text);
  Result:=node;
end;
//---------------------------------------------------------
//---------------------------------------------------------
//TO DO :  把XML文档里的值绑定到树中
//参数 :   XML文档路径
//返回 :  无
procedure TMainForm.TreeViewBind(xmlFile:string);
var
inXmlDocument:IXMLDocument;
xmlnode : IXMLNode; //指向XML根结点
tempXmlNode,tempXmlNode2:IXMLNode;
{xmlList : IXMLNodeList;}
node,childNode: TTreeNode;
nodes:TTreeNodes;
i,j:integer;
DEPARTMENTName:string;
begin
  self.ChannelTreeView.Items.Clear;
  nodes:= self.ChannelTreeView.Items;
  InXmlDocument := TXMLDocument.Create(nil);
  InXmlDocument.Active := True;
  InXmlDocument.Version := '1.0';
  InXmlDocument.Encoding :='GB2312';
  InXmlDocument.LoadFromFile(xmlFile);
  xmlnode:=InXmlDocument.DocumentElement;
  node:= AddNode(xmlnode.Attributes['NAME'],nodes);
 for i:=0 to xmlnode.ChildNodes.Count-1 do
 begin
     tempXmlNode := xmlnode.ChildNodes.Nodes[i];
     DEPARTMENTName:=tempXmlNode.Attributes['NAME'];
     childNode:=AddChildNode(DEPARTMENTName,'a',node,nodes);
      for j:=0 to tempXmlNode.ChildNodes.Count-1 do
      begin
       tempXmlNode2 := tempXmlNode.ChildNodes.Nodes[j];
       AddChildNode(tempXmlNode2.Attributes['NAME'],tempXmlNode2.Attributes['LINK'],childNode,nodes);
      end;
 end;
end;
//---------------------------------------------------------
然后是事件加载procedure TMainForm.FormShow(Sender: TObject);
begin
TreeViewBind('1.xml');
end;
procedure TMainForm.ChannelTreeViewChange(Sender: TObject;
  Node: TTreeNode);
begin
if Node.Data<>nil then
Showmessage(pchar(Node.Data));
end;

解决方案 »

  1.   

    偶T啊T啊。。T没力气了 找了好久资料
      

  2.   

    问题都在AddChildNode函数中
    可以改为:
    function TMainForm.AddChildNode(text, value: string; node: TTreeNode; ParentNode: TTreeNodes): TTreeNode;
    var
      nodes: TTreeNode;
       p:  pchar;
    begin
      GetMem(p,length(value)+1);//把由ActiveX分配的内存拷贝到自己分配的内存中
      strcopy(p,pchar(value));
      nodes := ParentNode.AddChildObject(node, text,p);
      Result := nodes;//记得释放这段内存
    //  memo1.lines.add(Format('%p %s,%p',[@(pchar(Value)^),Pchar(p),@(nodes.Data^)]));
    end;分析:在这一句中,
     AddChildNode(tempXmlNode2.Attributes['NAME'],
     tempXmlNode2.Attributes['LINK'], childNode, nodes);tempXmlNode2.Attributes['LINK'],这个对象分配的内存是由XML ActiveX来管理的
    所以不能把它的指针作为node.data保存来长期使用,这个在API调用中也是存在这个问题;
    如gethostbyname 函数,它返回的指针所指向的内存是由Windows分配的,在一段时间以后
    该指针可能就会无效.
      

  3.   

    同意上面的。
    如果方便,请帮我儿子投一票
    http://www.nutricia.com.cn/view.asp?id=736
    谢谢。
      

  4.   

    谢谢。guanxy(guanxy) 。你说的没错。。这下已经解决了