Форум: "Базы";
Текущий архив: 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.036 c