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

Вниз

TTreeNode.Data - как правильно использовать?   Найти похожие ветки 

 
П7   (2004-09-20 10:00) [0]

Мастера, подскажите пожалуйста сабж.
Вот кусок кода:

type
 TMyRec = record
   field1 : integer;
   field2 : integer;
 end;

var
 Node : TTreeNode;
 MyRec : TMyRec;
begin
 Node := treList.Items.Add( nil, "Text" ); //treList : TTreeView
 // Заполняю MyRec
 MyRec.field1 := 77;
 Node.Data := @MyRec;
end;

Далее пытаюсь получить данные так:

var
 MyRec2 : TMyRec;
begin
 MyRec2 := TMyRec( treList.Selected.Data^ );
end;

В итоге иногда получаю нормальное значение, а иногда какую-то белиберду. Вероятно нужно как-то выделять память, хотя вроде бы присваивается указатель на переменную. Как быть?


 
Alx2 ©   (2004-09-20 10:04) [1]

У тебя заносится в Data указатель на переменную в стэке.
Естественно, никакой гарантии сохранности нет.
Объявление MyRec : TMyRec надо сделать глобальным.

А вообще гораздо чаще выделяют память.


 
KSergey ©   (2004-09-20 10:05) [2]

Надо выделить память (а не просто переменную, которая умирает после выхрда из ф-ции, где объявлена)
Записать указатель в Data
Где надо - использовать
После - не забыть всю память освободить.


 
Гаврила ©   (2004-09-20 10:06) [3]

type
PMyRec = ^TMyRec;
TMyRec = record
  field1 : integer;
  field2 : integer;
end;

var
Node : TTreeNode;
MyRec : PMyRec;
begin
Node := treList.Items.Add( nil, "Text" ); //treList : TTreeView
// Заполняю MyRec
New(MyRec);
MyRec.field1 := 77;
Node.Data := MyRec;
end;

И не забыть освободить потом память под запись (dispose)


 
П7   (2004-09-20 10:11) [4]

Эээ... Код условен. Запись объявляется глобально, как и переменная...
Вообще-то у меня есть класс...

 PP7TypeItem = ^P7TypeItem;
 P7TypeItem = record
   Typ : integer;
   // и т.д.
 end;

 P7TypeList = class
   Items : array of P7TypeItem;
   Count : Cardinal;

   function Add( item : P7TypeItem ) : PP7TypeItem;
   procedure Clear();
 end;

Есть глобальная переменная:

var
 TypeList : P7TypeList;

И если совсем точно, то делаю я так:

var
 ti : P7TypeItem;
 Node : TTreeNode;
begin
 Node := treList.Items.Add( nil, "Text" ); //treList : TTreeView
 ti.Typ := 0;
 // и т.д.
 Node.Data := QstTypeList.Add( ti );
end;

ВотЪ... После этого данные могут теряться, а могут и нет...


 
Erik1 ©   (2004-09-20 10:12) [5]

LOL
А ты знаеш, что такое область видимости переменых? MyRec уничтожается сразу после выполнения твоей процедуры! Делай так:
PMyRec = TMyRec^;
........
Procedute SetValue(Value: Integer);
var
Node : TTreeNode;
MyRec : PMyRec;
begin
New(MyRec);
MyRec.field1 := Value;
Node := treList.Items.Add( nil, "Text" );
Node.Data := MyRec;
....
Только незубудь при освобождении сделать Dispose(PMyRec(Node.Data));
Кроме того есть метод Items.AddObject и Help+example на TTreeNode.Data


 
П7   (2004-09-20 10:19) [6]


> Erik1 ©   (20.09.04 10:12) [5]

Сам ты ЛОЛ. Внимательнее ветку нужно читать. Код в первом посте достаточно условен... К тому же как ты мог заметить там нет ни одного слова, вроде function и procedure. Считай что это глобальные begin..end. Вот.

> Гаврила ©   (20.09.04 10:06) [3]

Спасибо, вроде как помогло, хотя ещё тестить нужно будет подольше...


 
Гаврила ©   (2004-09-20 10:45) [7]

Кстати, переменные эти должны быть именно локальными


 
Iconka ©   (2004-09-20 11:15) [8]

Псмотри в сторону TreeView.OnCreateNodeClass.
Создай потомок TTreeNode c нужными тебе дополнительными полями.


 
П7   (2004-09-22 09:38) [9]


> Iconka ©   (20.09.04 11:15) [8]

Вы можете поподробнее рассказать об TreeView.OnCreateNodeClass?


 
Miralex ©   (2004-09-22 10:10) [10]


> TTreeNode.Data - как правильно использовать?


В примерах уи тя в Delphi олжен валяться TreeDirDemo.
Там хорошо видно как можно использовать TTreeNode.Data!

Код:
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 ComCtrls, StdCtrls, FileCtrl, ImgList, Menus;

Type
 PDirFile = ^TDirFile;
 TDirFile = Record
   Path: String;
   Name: String;
   Time: Integer;
   Size: Integer;
   Attr: Integer;
   End;

type
 TForm1 = class(TForm)
   TreeView1: TTreeView;
   StatusBar1: TStatusBar;
   ImageList1: TImageList;
   PopupMenu1: TPopupMenu;
   Replace1: TMenuItem;
   Find1: TMenuItem;
   N2: TMenuItem;
   PasteSpecial1: TMenuItem;
   Paste1: TMenuItem;
   Copy1: TMenuItem;
   Cut1: TMenuItem;
   N3: TMenuItem;
   Repeatcommand1: TMenuItem;
   Undo1: TMenuItem;
   procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
   procedure FormCreate(Sender: TObject);
   procedure TreeView1Expanding(Sender: TObject; Node: TTreeNode;
     var AllowExpansion: Boolean);
   procedure TreeView1Collapsed(Sender: TObject; Node: TTreeNode);
   procedure TreeView1Deletion(Sender: TObject; Node: TTreeNode);
   procedure TreeView1CustomDrawItem(Sender: TCustomTreeView;
     Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
 private
   Procedure AddNode(Const SR: TSearchRec; Const Path: String; Const Node: TTreeNode);
   Procedure AddRootNode(Const SR: TSearchRec; Const Path: String; Const RootName: String; Const Node: TTreeNode);
   Procedure ViewStatusBar(DF: TDirFile);
   Procedure GetDiskList(Var Value: String);

 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
Var
 DF: TDirFile;
begin
 If TreeView1.Visible And Assigned(TreeView1.Selected) Then Begin
   DF := TDirFile(TreeView1.Selected.Data^);
   ViewStatusBar(DF);
   End
end;

procedure TForm1.ViewStatusBar(DF: TDirFile);
begin
 StatusBar1.Panels[0].Text := Format("%s", [DF.Name]);
 StatusBar1.Panels[1].Text := Format("%d", [DF.Size]);
end;

procedure TForm1.FormCreate(Sender: TObject);
Var
 SR: TSearchRec;
 Disks: String;
 A: Shortint;
begin
//Form1.PopupMenu1.Items[1].Visible := false;

 With SR Do Begin
   Size := 0;
   Attr := faDirectory;
   End;
 GetDiskList(Disks); // Список существующих дисков
 //For A := 1 To Length(Disks) Do Begin
   SR.Name := "C:\Program Files\";
   AddRootNode(SR, "", "rootdir", Nil);
   SR.Name := "D:\Program Files\Borland\Delphi7\";
   AddRootNode(SR, "", "borlanddir", Nil);
   //End;
end;

procedure TForm1.AddRootNode(Const SR: TSearchRec; Const Path: String; Const RootName: String; Const Node: TTreeNode);
Var
 CNode: TTreeNode;
 P: PDirFile;
begin
 With SR Do If (Name = ".") Or (Name = "..") Then Exit;
 New(P);
 P^.Path := Path;
 P^.Name := SR.Name;
 P^.Time := SR.Time;
 P^.Size := SR.Size;
 P^.Attr := SR.Attr;
 CNode := TreeView1.Items.AddChildObject(Node, rootname, P);
 If (P^.Attr And faDirectory) <> 0 Then Begin
   CNode.HasChildren := True;
   CNode.ImageIndex := 2;
   CNode.SelectedIndex := 2;
   End
 else CNode.ImageIndex := 1;
end;

procedure TForm1.AddNode(Const SR: TSearchRec; Const Path: String; Const Node: TTreeNode);
Var
 CNode: TTreeNode;
 P: PDirFile;
begin
 With SR Do If (Name = ".") Or (Name = "..") Then Exit;
 New(P);
 P^.Path := Path;
 P^.Name := SR.Name;
 P^.Time := SR.Time;
 P^.Size := SR.Size;
 P^.Attr := SR.Attr;
 CNode := TreeView1.Items.AddChildObject(Node, P^.Name, P);
 If (P^.Attr And faDirectory) <> 0 Then Begin
   CNode.HasChildren := True;
   CNode.ImageIndex := 2;
   CNode.SelectedIndex := 2;
   End
 else CNode.ImageIndex := 1;
end;

procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
 var AllowExpansion: Boolean);
var
 DF: TDirFile;
 SR: TSearchRec;
begin
 If Node.getFirstChild <> Nil Then Exit;
 DF := TDirFile(Node.Data^);
 If (DF.Attr And faDirectory) = 0 Then Exit;
 DF.Path := DF.Path + DF.Name + "\";
 If FindFirst(DF.Path + "*", faAnyFile, SR) = 0 Then Begin
   AddNode(SR, DF.Path, Node);
   While FindNext(SR) = 0 Do
     AddNode(SR, DF.Path, Node);
   FindClose(SR);  // Освобождение ресурсов
   End;
end;

procedure TForm1.TreeView1Collapsed(Sender: TObject; Node: TTreeNode);
begin
 Node.DeleteChildren; // удаление дочерней ветки
 Node.HasChildren := True;
end;

procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
 Dispose(PDirFile(Node.Data)) // освобождение памяти для каждого из узлов
end;

procedure TForm1.GetDiskList(var Value: String);
Var
 A: Integer;
 A2: Cardinal;
Begin
 Value := "";
 A2 := GetLogicalDrives;
 For A := 2 To 31 Do
   If (A2 And (1 Shl A)) <> 0 Then
     Value := Value + Char(Ord("A")+A);
end;

procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
 Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if cdsSelected in State then
 begin
 Sender.Canvas.Font.Style := Sender.Canvas.Font.Style + [fsUnderline];
 end;

end;

end.


 
Гаврила ©   (2004-09-22 10:28) [11]


> П7   (22.09.04 09:38) [9]
>
> > Iconka ©   (20.09.04 11:15) [8]
>
> Вы можете поподробнее рассказать об TreeView.OnCreateNodeClass?


type
 TMyTreeNode = class(TTreeNode)
   Fielld1, Field2: Integer;
 end;

//Событие TTreeView.OnCreateNodeClass

procedure TForm1.TreeView1CreateNodeClass(Sender: TCustomTreeView;
 var NodeClass: TTreeNodeClass);
begin
 NodeClass:=TMyTreeNode;
end;

После этого все узлы дерева на самом деле создаваться будут класса TMyTreeNode, и их можно смело типизировать под этот класс.

Действительно, этот вариант самый грамотный


 
П7   (2004-09-22 11:43) [12]


> Гаврила ©   (22.09.04 10:28) [11]

Спосибо, сейчас так и делаю, ошибок пока не обнаружил.
Вопрос закрыт.



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

Форум: "Основная";
Текущий архив: 2004.10.10;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.052 c
3-1095050633
Jann
2004-09-13 08:43
2004.10.10
работа БД работающими под SQL Server


11-1073918606
miek
2004-01-12 17:43
2004.10.10
Бартову и Кладову: глюки в XHelpGen


14-1094544398
9k33
2004-09-07 12:06
2004.10.10
Альтернатива для RENT A CODER


4-1093965391
Arnold
2004-08-31 19:16
2004.10.10
Известен Handle окна, как узнать какой его тип (TForm,TButton..)


1-1096276854
DelphiLexx
2004-09-27 13:20
2004.10.10
Перетаскивать форму в клиентской части





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский