Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > что-то происходит с экземплярами класса в списке


Автор: ragzovskii 19.12.2009, 22:38
Доброго времени суток.

Код

procedure TController.GenerateTree(treeView: TTreeView);
var
  hasParent: Boolean;
  node: TResource;
begin
  nodeList:=TTreeNodes.Create(treeView);
  repeat
//здесь ищутся корни дерева (элементы, для которых флаг hasParent=false)
    if hasParent=False then
    begin
      node:=TResource(nodeList.Add(nil,IntToStr(parentList[current])));
      node.id:=parentList[current];
      repeat
        ExplodeNode(node);
        node:=TResource(node.getNextSibling);
      until node=nil;
    end;
    current:=current+1;
    hasParent:=False;
  until current>length(parentList)-1;
  NameTree;
end;

procedure TController.ExplodeNode(treeNode: TResource);
var
  I: Integer;
  tempList: Array of integer;
  tempNode: TResource;
begin
    SetLength(tempList,GetChildrenCount(StrToInt(treeNode.Text)));
    getChildren(StrToInt(treeNode.Text),tempList);
    for I := 0 to Length(tempList)-1 do
    begin
      tempNode:=TResource(nodeList.AddChild(treeNode,IntToStr(tempList[I])));
      ExplodeNode(tempNode);
    end;
end;

procedure TController.NameTree;
var
  node: TResource;
  I: Integer;
begin
  node:=TResource(nodeList.GetFirstNode);
  I:=0;
  repeat
    node.id:=StrToInt(node.text);
    node.Text:=nameList[node.id-1];
    node.name:=node.Text;
    node.position:=I;
    node:=TResource(node.GetNext);
    I:=I+1;
  until node=nil;

end;


процедура generateTree работает с некоторыми списками, в которых ищет корневые вершины дерева, и раскрывает их по порядку с помощью процедуры explodeNode.
ошибка возникает в методе NameTree. на втором проходе, node.Text='' и метод StrToInt отваливается. Если этот метод не вызывать, то дерево заполняется так, как надо, но в названиях вершин стоят ID (издержки метода generateTree). дебаггер показывает, что со списком nodeList творится черт знает что: если метод ExplodeNode вызывается более, чем 2 раза, то в списке NodeList значения полей уже созданных экземпляров содержат неправильные данные. Если вместо node:=TResource(node.GetNext) написать node:=TResource(node.GetNextSibling), то компилятор не может скомпилировать юнит, который к этим двум вообще никакого отношения не имеет.

что самое интересное: этот код работал корректно.
есть какие-нибудь идеи?

Автор: dvamaster 22.12.2009, 07:38
судя по всему TResource наследник TTreeNode

тогда собственные поля в TResource будут отсутствовать в памяти (не выделены), и будут писаться непонятно куда!
при добавлении создавай TResource и  используй AddNode


а если это совершенно иной класс то тем более работать не может!!!
в этом случае используй AddChildObject где аргумент Ptr есть объект TResource
Код

AddChildObject(parent, 'строка', Pointer(@res); // где res: TResource


доступ к TResource
Код

res := TResource(Node.Data); // где res: TResource


при уничтожении дерева не забудь деструктировать все TResource

Автор: ragzovskii 24.12.2009, 20:03
Действительно! я совсем забыл, что использую не перегруженные методы. Спасибо smile
Правда я уже полностью переписал этот код, но на будущее пригодится.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)