Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Treeview und datapointer... (https://www.delphipraxis.net/12637-treeview-und-datapointer.html)

barnti 1. Dez 2003 15:36


Treeview und datapointer...
 
Hallo,

ich möchte Informationen in einen Treeview überführen. Dazu mache ich folgendes:

Delphi-Quellcode:
...
 LastInserted.Data:= ParamArray[i].FieldByName(ParamArray[i].FieldList[0].FieldName);
...
LastInserted ist vom Typ TTreeNode, Im ParamArray werden 3 Querys übergeben, um diese im Treeview darzustellen.
Den Datapointer lasse ich auf ein Feld des Datasets der Query zeigen.

Meine Frage: Wie kann ich die gespeicherte Information wieder auslesen? Kann ich das überhaupt? Oder muss ich den Pointer auf etwas anderes zeigen lassen. Ich möchte ja eigentlich der Wert des Feldes haben!

Danke & Gruß,

Barnti

barnti 3. Dez 2003 08:06

Re: Treeview und datapointer...
 
Hmm,

ich versuche das noch mal zu verdeutlichen:

Ich möchte die Informationen meiner Query in eine Treeview überführen. Dazu möchte ich in jedem Knoten das aktuelle Record speichern. In Etwa so:

Delphi-Quellcode:
...                          // einfügen eines neuen Knotens mit der Betitelung
                              // der ID des akt. records
LastInserted:= Treeview.Items.AddChild(node,Query.FieldByName('ID'));

LastInserted.Data:= Query.?  // wie bekomme ich hier einen Zeiger auf das aktuelle
                             // Record gespeichert?????
Die zweite Frage ist wie kann ich die Informationen wieder auslesen, wenn ich z.B. den Inhalt des pointers (Record der Query) an einer bestimmten Stelle, sprich ein Feld, auslesen möchte?

Kann jemand helfen. Meine Pointer-Kenntnisse sind etwas eingestaubt!

Danke,

Barnti

oki 3. Dez 2003 08:19

Re: Treeview und datapointer...
 
Hi,

grundsätzlich ist die Eigenschaft Data des TTreeNode vom neutralen Typ Pointer. Alles was du mit einem typisierten Pointer vorrätig hast kannst du jetzt dort hinterlegen. Willst du den Pointer auf deine Daten zurückhaben, so mache einfach folgendes:
Delphi-Quellcode:
   MeinetTypPointerVariable := TypPointer(TreeView.Data);
Danach zur Sicherheit auf nil prüfen und du kannst mit deiner Variablen wie gewohnt weiterarbeiten. Das gilt so auch für Objekte!

Hier auch mal ein Bsp.:

var MObject : TObject;
begin
MyObject := TObject.Create;
MyTreeNode.Data := Pointer(MyObject);
....
MyObject := TObject(MyTreeNode.Data);
// und dann weiter auf Members von MyObject wie gewohnt zugreifen
MyObject.Free;
end;
[delphi]

Gruß oki

barnti 3. Dez 2003 08:35

Re: Treeview und datapointer...
 
Hallo Oki,

ich habe mal nach Deinem Beispiel gearbeitet:

Delphi-Quellcode:
var LastInserted: TTreenode;

...
 
LastInserted.Data:= Pointer(ParamArray[i].DataSource.DataSet.Fields);

Fields:= TFields(Lastinserted.Data^); [edit] Ok, hier nur TFields
                                             (Lastinserted.Data). Aber warum? 
                                       Muss ich nicht auf den Inhalt zugreifen? [/edit]        

ShowMessage(Fields.DataSet.FieldByName('ID').AsString); // An dieser Stelle
                                                               // steigt Delphi mit

                                                   // einer Schutzverletzung aus...
Ansonsten habe ich Deine Anweisungen eingehalten. Der Pointer kann nicht nil sein, da ich diesen ja vorher zuweise.

Was mache ich jetzt noch falsch?

Gruß,

Barnti

oki 3. Dez 2003 10:16

Re: Treeview und datapointer...
 
Hi,

mir fehlt offensichtlich noch ein Stück vom Anfang Deiner Anwendung. Aber grundsätzlich mal folgendes.

Wenn du eine aktuelle Querry im Data halten willst, dann mußt du natürlich auch sicherstellen, dass die Instanz auf die dein Pointer zeigt noch vorhanden ist. Desweiteren fällt mir auf, dass du hier nicht den Zeiger zuweist, sondern den Inhalt( durch die dereferenzierung ^).

Ich denke, die korrekte Zeile muß so lauten:
Delphi-Quellcode:
Fields:= TFields(Lastinserted.Data);

Gruß oki

MyRealName 3. Dez 2003 12:42

Re: Treeview und datapointer...
 
Ist mir auch mit Schrecken aufgefallen, daß Bezug auf die ParamListe eines Queries genommen wird, daß klicks später vielleicht schon zerstört wird... :wall:

Wenn Du unbedingt ein paar Daten speichern mußt, mach Dir ein record :

RMyData = packed record
ID : integer;
// Bla
end;
PMyData = ^RMyData;

function NewData: PMyData;
begin
New(Result);
end;



Dann knall Dir das in den TreeView :
...
LastInserted.Data := NewData;
...

und nun bearbeiten :

...
PMyData(LastInserted.Data)^.ID := Fields[0].AsInteger; // weißt schon ;-)
...


LG, MyRealName

barnti 3. Dez 2003 13:25

Re: Treeview und datapointer...
 
Hallo,

ich habe es mit dem Beispiel von Oki hinbekommen. Danke, Oki!

Zitat:


Ist mir auch mit Schrecken aufgefallen, daß Bezug auf die ParamListe eines Queries genommen wird, daß klicks später vielleicht schon zerstört wird...

Das verstehe ich nicht. Ich speichere in Data den Verweis auf den aktuellen Datensatz...
Die Prozedur dient lediglich dem Darstellen einer oder mehrerer Querys als Treeview. Mit einem Klick kann man dann auf den Inhalt des Trees(data) zugreifen...

Besteht da ein Problem, welches ich nicht sehe?

Gruß & Danke,

Barnti

MyRealName 3. Dez 2003 13:43

Re: Treeview und datapointer...
 
Wenn Du ein Query benutzt, um immer wieder neue Daten zu in die Datenbank zu setzen, dann werden die Field- und Param-Listen des Query-Objekts immer wieder zerstört bei jeder neuen Query und damit die Pointer, die Du speicherst, ungültig. Zum anderen ist es eine sehr ineffiziente Methode, Objekte zu halten, nur wegen ein paar Variablen. Das ist die pure Verschwendung. Aber was sag ich, das ist ja heutzutage unter windows normal... Wenn ich da an die guten alten DOS-Zeiten denk, wo man mit Assembler um jedes Byte gefeilscht hat :coder:

MRN

oki 3. Dez 2003 13:52

Re: Treeview und datapointer...
 
Hi,

Natürlich hat myrealname recht mit dem thema Speicher. Das ist ein thema dessen sich barnti als nächstes annehmen sollte. Also eine Möglichkeit finden, mit der nur das im Tree gehalten wird was nötig ist. Trees sind halt auch mal schnell mit vielen Nodes gefüllt und wenn dann an jedem Node ein Speicherjumbo hängt gehen die Ressourcen schneller den Bach runter als man gucken kann.

Grundsätzlich wollte ich aber erst mal das Thema zur Lösung bringen. (Erster Schritt vor zweitem).

Gruß oki

MyRealName 3. Dez 2003 14:09

Re: Treeview und datapointer...
 
Tree's sind schnell gefüllt mit Nodes ? :gruebel:
Womit programmierst Du ? Delphi wohl eher ned *haha*...
Also die Wrapper-Klasse von Delphi suckt in der Beziehung total. Erstell mal auf die "Schnelle" 10000 nodes *muhahahaha*

Am besten kann man sehen, wie langsam sowas ist, wenn man mal 10.000 TLabels erzeugt. Einmal einfach nur so und einmal mit Parent...

MRN

oki 3. Dez 2003 14:16

Re: Treeview und datapointer...
 
Hi MyRealName,

schnell ist relativ! Mit BeginUpdate und EndUpdate kann man im Verhältnis aber ne Menge rausholen!

Gruß oki

MyRealName 3. Dez 2003 14:19

Re: Treeview und datapointer...
 
Ich bevorzuge an der Stelle virtuelle ListViews, aber ist halt Geschmackssache. Bei mir auf Arbeit ist Speed wichtig...

LG, MRN

barnti 3. Dez 2003 15:22

Re: Treeview und datapointer...
 
Hallo ihr,

das sind alles berechtigte Einwände. Ich benutze aber nur eine sehr begrenzte Zahl von Einträgen, um diese im Tree zu speichern(max. 1000). Da ich immer nur einen Baum zur Zeit mit Daten fülle und nach dem Beenden der Ansicht das ganze wieder lösche, sollte es keine Probleme geben.

Oder doch?

Gruß,

Barnti

MyRealName 3. Dez 2003 15:51

Re: Treeview und datapointer...
 
Das kommt ja drauf an, was Du in der Zwischenzeit machst ;-)

barnti 5. Dez 2003 15:39

Re: Treeview und datapointer...
 
Hallo,

ich habe mir überlegt keine Pointer zu verwenden. Statt dessen speichere ich Informationen im Text der Nodes. Aus dieser Ansicht werden dann Datensätze angelegt und in der DB gespeichert. Da ich die Datensätze sperre, wenn ich diese im Tree darstelle. Dürfte es keine Probleme mit Veränderungen in der DB geben.

Es wird also immer nur ein Baum aus Daten der DB generiert, diese Daten für den Schreibzugriff gesperrt und nach dem Bearbeiten wieder zurückgeschrieben.

Danke für das Interesse,

Gruß,

Barnti

barnti 11. Dez 2003 12:16

Re: Treeview und datapointer...
 
Hallo,

und jetzt habe ich doch noch ein Problem:

Ich schaffe es nicht den aktuellen Datensatz in meinem Pointer zu speichern. Auf was muss ich denn den Pointer zeigen lassen um den aktuellen Datensatz zu Speichern?

Was ich erreichen möchte ist, dass ich in den Knoten durch den Verweis mit dem Pointer den dazu gehörigen Datensatz zeige.
Geht das? Und wenn ja, wie?

Danke für eure Hilfe + Gruß,

Barnti

Touchdown 11. Dez 2003 12:49

Re: Treeview und datapointer...
 
@barnti


Auf Pointer zu verzichten würde ich dir nicht raten, deine Möglichkeiten wären doch sehr eingeschrängt!

Und vor allem warum willst du darauf verzichten? Weil du noch nicht verstanden hast wie man damit arbeitet?

Dann setz dich lieber wieder hin und mach so lange bis es läuft, es ist auch nicht wirklich schwer!

Wegen der Performance kann es nicht sein, dass würde alles nicht zählen :-D

PS: Was du vermutlich noch nicht verstehst: Wenn du zwei Pointer auf ein Objekt hast und einen freigibtst, zeigen beide Pointer auf ungültigen Speicherbereich! Ein Pointer könnte TTreeNode.Data sein !!!!

barnti 11. Dez 2003 13:15

Re: Treeview und datapointer...
 
Hallo Touchdown,

das Problem sind aktuell nicht die Pointer, sondern das worauf diese zeigen sollen.

Ich möchte unbedingt auf die Property "Pointer" zurückgreifen, da ich alle Daten des aktuellen records benötige.
Die Freigabe des Speicherbereichs dürfte keine Probleme verursachen. Ich gehe wie folgt vor:
Ich rufe die betreffenden Datensätze in der DB ab und speichere diese in der Treeview-Ansicht. Jeder Knoten so als Pointer auf den Inhalt des jeweiligen Records zeigen. Die Query bleibt dabei unberührt. Ich lösche, update und mache auch sonst nix mit dem aktuellen Inhalt des Datasets.
Ich möchte aber jetzt die Informationen zu einem Knoten des Treeviews weiterverarbeiten. Zum B. mit einem Klick auf einen Knoten, mir informationen zu diesem, und damit zu dem zugehörigen Record anzeigen lassen.

Es geht also lediglich um verschiedene Ansichten der zugrundeliegenden Tabellenstruktur.

Sollte doch möglich sein jeden Knoten beim Darstellen im Treeview durch einen Pointer auf ein Record des Datasets zeigen zu lassen...?!

Gruß,
Barnti

barnti 11. Dez 2003 13:51

Re: Treeview und datapointer...
 
Hallo,

um die ganze Sache zum Abschluss zu bringen:

Ich erzeuge mir einen benutzerdefinierten Datentyp, welcher als record alle in der Query vorhandenen Daten aufnehmen kann. Beim Schreiben der Daten aus der Query in den Treeview erzeuge ich einen Pointer vom Typ des record-Datentyps und lasse die Property
"Node.Data" aus diesen Speicherbereich zeigen.

So steht jetzt in jedem Knoten die Info zum zugehörigen Tabelleneintrag.

Danke für eure Aufmerksamkeit und Tschüß,

Barnti


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz