2012-03-20 5 views
3

Я хочу просмотреть XML с помощью TTreeView. Для того, чтобы связать TreeView узлы с узлами XML с атрибутами я использовал следующий синтаксис:Связывание узла XML с узлом просмотра дерева

var tv: TTreeView; tn1, tn2: TTreeNode; xn: IXMLNode; 

if xn.AttributeNodes.Count > 0 then 
    tn2 := tv.Items.AddChildObject(tn1, xn.NodeName, @xn) 
else 
    tn2 := tv.Items.AddChild(tn1, xn.NodeName); 

.., а затем в программе:

var tv: TTreeView; pxn: ^IXMLNode; i: integer; 

pxn := tv.Selected.Data; 
for i := 0 to iXML.AttributeNodes.Count-1 do 
    ShowMessage (pxn^.AttributeNodes[i].LocalName + ' = ' + 
       pxn^.AttributeNodes[i].Text); 

, что приводит к исключению .. Насколько я может понять, что это связано с тем, что я указываю на интерфейс вместо объекта.

Можно ли ссылаться на фактический объект XML вместо интерфейса? Что произойдет с этой ссылкой, если новые XML-узлы будут вставлены или удалены из дерева?

Или есть другое прямое решение?

Вся помощь оценивается!

ответ

4

не использовать @ и^операторы, интерфейсы уже ссылается

первый код:

var tv: TTreeView; tn1, tn2: TTreeNode; xn: IXMLNode; 

if xn.AttributeNodes.Count > 0 then 
    tn2 := tv.Items.AddChildObject(tn1, xn.NodeName, Pointer(xn)) 
else 
    tn2 := tv.Items.AddChild(tn1, xn.NodeName); 

второй код (не забудьте проверить, если данные назначены)

var tv: TTreeView; pxn: IXMLNode; i: integer; 

if Assigned(tv.Selected) and Assigned(tv.Selected.Data) then begin 
    pxn := IXMLNode(tv.Selected.Data); 
    for i := 0 to iXML.AttributeNodes.Count-1 do 
    ShowMessage (pxn.AttributeNodes[i].LocalName + ' = ' + 
        pxn.AttributeNodes[i].Text); 
end; 

Просто найдите в сети дополнительную информацию о интерфейсах, классах и различиях между ними. Хорошая информация: http://blog.synopse.info/post/2012/02/29/Delphi-and-interfaces

+0

Спасибо! Помогли мне много ;-) – user1280956

+0

Интерфейсы подсчитаны. Сохранение указателя интерфейса в 'TTreeNode' не увеличивает счетчик ссылок автоматически. Я бы либо вручную вызывал '_AddRef()' и '_Release()' на интерфейсе при добавлении/удалении его в/из 'TTreeNode', либо лучше хранить интерфейс в' TInterfaceList', а затем хранить индекс списка в 'TTreeNode' вместо фактического указателя интерфейса. –

Смежные вопросы