Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.11.28;
Скачать: CL | DM;

Вниз

Указатель на Record при добавлении узлов в TreeView   Найти похожие ветки 

 
Dr. Andrey   (2004-11-02 09:16) [0]

Справочник подразделений на нем 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 работает в первом случае.


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

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

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

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


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

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


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


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

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

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

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

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


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

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


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


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

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


 
}|{yk ©   (2004-11-02 15:13) [6]

{
Формат елементів усіх дерев
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;



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

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

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

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



Страницы: 1 вся ветка

Текущий архив: 2004.11.28;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.035 c
1-1100173549
kirov_igor
2004-11-11 14:45
2004.11.28
printer


1-1100526945
<< TEster
2004-11-15 16:55
2004.11.28
Как отличить файл от каталога ?


1-1100507261
Sun bittern
2004-11-15 11:27
2004.11.28
PChar and DLL


1-1100263948
Sandman25
2004-11-12 15:52
2004.11.28
Blob и Variant


1-1100546051
DIS
2004-11-15 22:14
2004.11.28
добавление записи в реестр.