Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Указатель на Record при добавлении узлов в TreeView [D6, MS ACCESS]


Dr. Andrey ©   (2004-11-02 09:16:00) 

Справочник подразделений на нем TreeView.
Заполняем из RST: Recordset
...

wA,wB,wC: Word; sS: String;
...

With RST do begin
while not Eof do begin
 wA:= Fields[0].Value; //Код подразделения-родителя
 wB:= Fields[1].Value; //Код подразделения
 wC:= Fields[2].Value; //Код вида учета
 sS:= Fields[3].Value; //Наименование подразделения

 Для поиска родительского узла написал функцию FindUzel

 MyNode:= TreeView1.Items.AddChildObject(FindUzel(pWordwA)),  sS, PWord(wB));
end;
end;

function TForm_Derevo.FindUzel(pP:Pointer):TTreeNode;
var W: Word;
begin
if pP = nil then begin Result:= nil; Exit; end;
for W:= 0 to TreeView1.Items.Count-1 do
 if pP = TreeView1.Items.Item[W].Data then begin result:= TreeView1.Items.Item[W]; break; end;
end;

Всё работает. Но в Data узлов нужно передавать указатель не на число (КодПодразделения), а на запись(КодПодразделения и КодВидаУчета.
Для этого описал тип данных PMyTVrec
MyTVrec= Record
  X: Word;
  Y: Word;
end;

PMyTVrec = ^MyTVrec;

в процедуре заполнения дерева:
...
PN: PMyTVrec
New(PN); PN^.X:= wB; PN^.Y:= wC;

MyNode:= TreeView1.Items.AddChildObject(FindUzel(pWordwA)), sS,PN);
...

function TForm_Derevo.FindUzel(pP: PMyTVrec):TTreeNode;
var W: Word;
begin
if pP = nil then begin Result:= nil; Exit; end;
for W:= 0 to TV_Derevo.Items.Count-1 do
 if WORD(pP)= PMyTVrec(TreeView1.Items.Item[W].Data)^.X then
 begin
  Result:= TreeView1.Items.Item[w];
  Break;
 end;

end;

При отладке значение PMyTVrec(TreeView1.Items.Item[W].Data)^.X = 0

Пробовал передавать в FindUzel число, а не указатель, но причина не в этом.
При циклическом обходе узлов в дереве функция находит нужный узел, но почему PMyTVrec(TreeView1.Items.Item[W].Data)^.X = 0?

Почему FindUzel работает в первом случае.


сергей1   (2004-11-02 16:47:00) [1]

Может я чего-то не понимаю в этой жизни, но работа с TreeView прекрасно обходиться без указателей и прочей лабуды.
Есть таблица, в которой храниться эта структура в виде (к примеру)

-Код элемента
-Название элемента
-Код родителя

Закачиваем их в treeview при помощи функций TreeView1.Items.Add, TreeView1.Items.AddChild().
Перемещаемся по дереву при помощи GetNext(), GetNextChild(), getFirstChild, getLastChild.
Также имеются полезные функции HasChildren, Parent.
Практически все что надо, решается этими функциями.
А то какие-то указатели ...


}|{yk   (2004-11-02 15:13:00) [2]

{
Формат елементів усіх дерев
mem_id - обовязково. Ідентифікатор елемента
mem_pid - обовязково. Ідентифікатор "батьківського" елемента
is_leaf -  обовязково. Ознака, чи є елемент елементом нижнього рівня
outlevel - обовязково. Рівень елемента
mem_order - обовязково. Порядковий номер в структурі
mem_name - обовязково. Назва елемента
mem_desc - обовязково. Описання елемента
mem_type - не  обовязково. Тип елемента
}
type
 TMyTreeNodes = record
   mem_id: integer;
   mem_pid: integer;
   is_leaf: boolean;
   outlevel: integer;
   mem_order: integer;
   mem_name: string;
   mem_desc: string;
   mem_type: string;
   changing: boolean; // чи змінювалися дані в обєкті
   inserting: boolean; //чи є обєкт доданим (без відображення в базі)
   ParentNode: TTreeNode;
 end;
 PTMyTreeNodes = ^TMyTreeNodes;

function TFrameBase.GenerateTree(Tree: TTreeView; DataSet: TDataSet): TFunctionResult;
var
 FunctionResult: TFunctionResult;
 vData: PTMyTreeNodes;
 Node, LastNode: TTreeNode;
begin
 Result.Successful := false;
// якщо дерево чи датасет не ініціалізовані, зупинити виконання
 if not Assigned(Tree) or not Assigned(DataSet) then
 begin
   Result.MessageOnError := 'Programmer error - not initilized objects on creating tree';
   Exit;
 end;
// якщо датасет не активний, то зупинити виконання
 if not DataSet.Active then
 begin
   Result.MessageOnError := 'Programmer error - not activated Dataset';
   Exit;
 end;
// очистимо дерево, якщо помилка зупинити виконання
 FunctionResult := ClearTree(Tree);
 if not FunctionResult.Successful then
 begin
   Result.MessageOnError := FunctionResult.MessageOnError;
   Exit;
 end;
// заповнимо дерево
 with DataSet do
 begin
   LastNode := nil;
   First;
   while not Eof do
   begin
     New(vData); // створимо елемент
     with vData^ do
     begin
       // заповнюємо його поля
       try
         mem_id := FindField('mem_id').AsInteger;
         mem_pid := FindField('mem_pid').AsInteger;
         is_leaf := boolean(FindField('is_leaf').AsInteger);
         outlevel := FindField('outlevel').AsInteger;
         mem_order := FindField('mem_order').AsInteger;
         mem_name := FindField('mem_name').AsString;
         mem_desc := FindField('mem_desc').AsString;
         if Assigned(FindField('mem_type')) then
           mem_type := FindField('mem_type').AsString
         else
           mem_type := 'general';
         changing := false;
         inserting := false;
       except on E: Exception do
         begin
           Result.MessageOnError := 'Programm error - incompatible structure' + #10#13 + 'Details: ' + E.Message;
           Exit;
         end;
       end;
     // якщо це елемент верхнього рівня, то додамо його в корінь
       if vData.outlevel = 1 then
       begin
         Node := Tree.Items.Add(nil, vData^.mem_desc);
         vData.ParentNode := nil;
       end
     // якщо елемент нижчого рівня, то додати як "сина"
       else if PTMyTreeNodes(LastNode.Data)^.outlevel < vData.outlevel then
       begin
         Node := Tree.Items.AddChild(LastNode, vData^.mem_desc);
         vData.ParentNode := LastNode;
       end
     // якщо елемент одного рівня, то додати як "брата"
       else if PTMyTreeNodes(LastNode.Data)^.outlevel = vData.outlevel then
       begin
         Node := Tree.Items.AddChild(LastNode.Parent, vData^.mem_desc);
         vData.ParentNode := LastNode.Parent;
       end
     // якщо елемент вищогого рівня, то знайти "підходящого батька" та додати як "сина"
       else if PTMyTreeNodes(LastNode.Data)^.outlevel > vData.outlevel then
       begin
         while PTMyTreeNodes(LastNode.Data)^.outlevel >= vData.outlevel do
           LastNode := LastNode.Parent;
         Node := Tree.Items.AddChild(LastNode, vData^.mem_desc);
         vData.ParentNode := LastNode.Parent;
       end;
     // занесення даних до структури
       Node.Data := vData;
       LastNode := Node;
       Next;
     end;
   end;
 end;
 Result.Successful := true;
end;


Семен Сорокин   (2004-11-02 15:06:00) [3]


> Dr. Andrey   (02.11.04 14:29) [4]

Покажите весь код процедуры заполнения дерева


Dr. Andrey   (2004-11-02 14:29:00) [4]

>Семён Сорокин
Извините, это была опечатка. Должно быть так:
function TForm_Derevo.FindUzel( pP: PWord):TTreeNode;


Семен Сорокин   (2004-11-02 09:55:00) [5]


> В FindUzel я передаю указатель только на код подразделения
> PWord (wA).

PWord(wA) - это не указатель, это приведение числа к типу PWord, указатель будет: @wA

опять же если Вы передаете PWord, то почему объявление ф-ции:

function TForm_Derevo.FindUzel( pP: PMyTVrec):TTreeNode;

Вы разберитесь и напишите правильно, что нужно и что не получается.


Dr. Andrey   (2004-11-02 09:46:00) [6]

MyNode:= TreeView1.Items.AddChildObject(FindUzel( pWord(wA)), sS,PN);
В FindUzel я передаю указатель только на код подразделения PWord (wA). Хотя пробовал и предлагаемый Вами вариант, т.е. передавать указатель типа PMyTVRec, пробовал передавать и число - эффект тот-же


Семен Сорокин   (2004-11-02 09:39:00) [7]

if WORD(pP)= PMyTVrec(TreeView1.Items.Item[W].Data)^.X then

может так надо:

if pP^.X = PMyTVrec(TreeView1.Items.Item[W].Data)^.X then


Наверх

Титульная страница Поиск, карта сайта Написать письмо