Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];

Вниз

Указатель на 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.039 c
3-1099197241
ali_t
2004-10-31 07:34
2004.11.28
размер колонок в TDBGrid


1-1100061003
officeman
2004-11-10 07:30
2004.11.28
про tStringList.Create


9-1091066199
Bonial
2004-07-29 05:56
2004.11.28
Хромирование объекта


14-1100077364
Igorek
2004-11-10 12:02
2004.11.28
OLTP и OLAP (одна или две)


14-1100199269
Knight
2004-11-11 21:54
2004.11.28
Как можно вылечить системные файлы...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский