Autor Beitrag
killavirus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 49

Win 2000
D5 Prof, D7 Prof
BeitragVerfasst: Fr 07.12.07 12:34 
Hallo zusammen,

Ich versuche in der Data Eigenschaft von TTreeNode oder PVirtualNode einen Pointer auf ein CollectionItem zu übergeben. Beim Auslesen des Pointers bekomme ich aber eine Zugriffsverletzung.

Mein Problem wurde auch schon in diesem Thema aufgegriffen aber leider nicht gelöst.
www.delphi-forum.de/...ght=pointer+treeview

Das erzeugen der Nodes erfolgt so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var Data: ^TDatabaseItem;
    DatabaseNode: PVirtualNode;
begin
    VST1.BeginUpdate;
    VST1.NodeDataSize:=SizeOf(PDatabaseItem);

    DatabaseNode:= VST1.AddChild(Nil);
    Data:=VST1.GetNodeData(DatabaseNode);
    VST1.ValidateNode(DatabaseNode, False);
    Data := @MyDatabaseItem;


Zugriff auf den Node:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var Data: ^TDatabaseItem;
begin
  Data := VST1.GetNodeData(VST1.FocusedNode);
  if data <> nil then begin
     ShowMessage(Data^.Name);
  end;


Die TDatabaseItem Klasse:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
  TDatabaseItem = class(TCollectionItem)
  private
    FName: string;
    FUsed: Boolean;
  protected
    function GetDisplayName: string; override;
  public
    constructor Create(Collection: TCollection); override;
    procedure Assign(Source: TPersistent); override;
  published
    property Name: string read FName write FName;
    property Used: Boolean read FUsed write FUsed;
  end;


Wer kann mir sagen was hier falsch läuft?

_________________
I need a girl whose name doesn't end in .JPG
Martin1966
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: Fr 07.12.07 12:56 
Ich glaube das funktioniert erstmal nur mit einem Record :gruebel:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
Type
  PNodeDataRecord = ^TNodeDataRecord;
  TNodeDataRecord = Record
     DatabaseItem: TDatabaseItem;
  End;


Deine Code-Ausschnitte müssten dann wie folgt geändert werden:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var Data: PNodeDataRecord;
    DatabaseNode: PVirtualNode;
begin
    VST1.BeginUpdate;
    VST1.NodeDataSize:=SizeOf(Data);

    DatabaseNode:= VST1.AddChild(Nil);
    Data:=VST1.GetNodeData(DatabaseNode);
    VST1.ValidateNode(DatabaseNode, False);
    Data.DatabaseItem := MyDatabaseItem;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var Data: PNodeDataRecord;
begin
  Data := VST1.GetNodeData(VST1.FocusedNode);
  if data <> nil then begin
     ShowMessage(Data^.DatabaseItem.Name);
  end;


Lg, Martin

_________________
Ein Nutzer der Ecke ;-)
killavirus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 49

Win 2000
D5 Prof, D7 Prof
BeitragVerfasst: Fr 07.12.07 14:45 
Zitat:

Ich glaube das funktioniert erstmal nur mit einem Record :gruebel:


Ja wenn ich in dem Record das ein Objekt von TDatabaseItem deklariere dann funktioniert das aber dann hab ich dann alles doppel gemoppelt da ich ja bereits ne Collection habe in dem mehrere CollectionItems drin sind.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
Type
  PNodeDataRecord = ^TNodeDataRecord;
  TNodeDataRecord = Record
     DatabaseItem: TDatabaseItem;
  End;


Die Eigenschaft Data ist doch vom Typ Pointer also muss es doch gehen das ich dort nen ganz normalen Pointer auf ne Klasse übergebe und diesen auslesen kann oder nicht? :gruebel:

Wenn ich nun den Record nehme und dort versuche den Pointer auf TDatabaseItem zu setzen dann bekomme ich beim Aufruf ebenfalls ne Zugriffsverletzung.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
Type
  PNodeDataRecord = ^TNodeDataRecord;
  TNodeDataRecord = Record
     PDatabaseItem: ^TDatabaseItem;
  End;


Kann man den nur nen Pointer auf einer Struktur verwenden?

_________________
I need a girl whose name doesn't end in .JPG
Klabautermann
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Veteran
Beiträge: 6366
Erhaltene Danke: 60

Windows 7, Ubuntu
Delphi 7 Prof.
BeitragVerfasst: Fr 07.12.07 14:57 
Hallo,

beim überfliegen ist mir folgendes aufgefallen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var Data: ^TDatabaseItem;
    DatabaseNode: PVirtualNode;
begin
    VST1.BeginUpdate;
    VST1.NodeDataSize:=SizeOf(PDatabaseItem);


Das kann so eigentlich nciht richtig sein, da PDatabaseItem ein Pointer ist und ein Pointer (in 32 Bit Programmen) eben immer 4 Byte groß ist. Korrekt müsste es so aussehen:


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var Data: ^TDatabaseItem;
    DatabaseNode: PVirtualNode;
begin
    VST1.BeginUpdate;
    VST1.NodeDataSize:=SizeOf(tDatabaseItem);


Wie gesagt das ist nur was mir beim schnellen drüber lesen aufgefallen ist. Ich weis nicht ob es der einzige/ausschlaggebende Fehler ist.

Gruß
Klabautermann
killavirus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 49

Win 2000
D5 Prof, D7 Prof
BeitragVerfasst: Fr 07.12.07 15:43 
Danke, es war zwar ein Fehler von mir aber leider war dieser nicht Ausschlaggebend für die Zugriffsverletzung.

Ich poste mal die ganze Funktion vielleicht liegt der Fehler ja auch wo anders.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TFMain.AddDatabase(MyDatabaseItem: TDatabaseItem);
var Data: ^TDatabaseItem;
    DatabaseNode: PVirtualNode;
begin
    VST1.BeginUpdate;
    VST1.NodeDataSize:=SizeOf(TDatabaseItem);

    DatabaseNode:= VST1.AddChild(Nil);
    Data:=VST1.GetNodeData(DatabaseNode);
    VST1.ValidateNode(DatabaseNode, False);
    Data := @MyDatabaseItem;

    VST1.EndUpdate;
end;


Meine letzte Vermutung wäre das es an "MyDatabaseItem" liegt :gruebel:

_________________
I need a girl whose name doesn't end in .JPG
gispos
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 94

WIN 7
XE10, D2007
BeitragVerfasst: Fr 07.12.07 22:15 
Du legst einen Pointer auf ein TDataBaseItem, was passiert denn mit dem
TDataBaseItem? Ist es bei dem Zugriff auf Data überhaupt noch vorhanden?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
var 
  PS: ^TStringList;

procedure Test;
var S: TStringList;
begin
  S:= TStringList.Create;
  PS:= @S;
  ShowMessage(PS^.ClassName);
  // Bis jetzt ist alles OK

  FreeAndNil(S);
  // Jetzt ist alles Futsch

  ShowMessage(PS^.ClassName); // geht nicht mehr!
end;


Noch etwas:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var Data: PNodeDataRecord;
begin
  Data := VST1.GetNodeData(VST1.FocusedNode);
  if data <> nil then begin
     ShowMessage(Data^.DatabaseItem.Name);
  end;
end;

Bringt so gut wie gar nichts wenn VST1 seinen Data-Pointer nicht mit NIL initiallisiert!
NIL ist nichts anderes als ein bool (True, False).

Nachtrag:
Die Lösung des Problems: Es wurde nur nach <> nil geprüft, richtig ist aber dies.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var Data: ^TDataBaseItem;
begin
  Data := VST1.GetNodeData(VST1.FocusedNode);
  If Assigned(TDataBaseItem(Data^)) then
     ShowMessage(Data^.Name);
 end;

Gruß gispos
killavirus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 49

Win 2000
D5 Prof, D7 Prof
BeitragVerfasst: Sa 08.12.07 11:29 
Ich habe nun noch etwas herumprobiert und habe nun eine Struktur erstellt in dem eine Pointer auf mein Objekt ist und zusätzlich habe ich das Objekt Global Deklariert und eine Globalen Pointer auf das Objekt gesetzt um zu prüfen ob ich auf das Objekt zugreifen kann.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
type                      // Struktur für 
 PMyRec = ^TMyRec;
 TMyRec = record
  FName: string;
  PDatabaseItem: ^TDatabaseItem;
end;

var
  PMyDatabaseItem: ^TDatabaseItem; // Globaler Pointer
  FMyDatabaseItem: TDatabaseItem; // Globales Objekt


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
var
    Data: PMyRec;
begin
   FMyDatabaseItem := Database.Items[0]; // Objekt wird zugewiesen
   PMyDatabaseItem := @FMyDatabaseItem;  // Pointer wird zugewiesen

   for x:=0 to 19 do begin
      DatabaseNode:= VST1.AddChild(NIL);
      Data:=VST1.GetNodeData(DatabaseNode);
      VST1.ValidateNode(DatabaseNode, False);
      Data.FName := 'TEST';
      Data.PDatabaseItem := Pointer(PMyDatabaseItem);

      Data:=VST1.GetNodeData(DatabaseNode);
      showMessage(Data.FName); // Ausagebe Struktur 
      showMessage(PMyDatabaseItem^.Name); // Ausgabe Globaler Pointer
      showMessage(Data.PDatabaseItem^.Name); // Ausgabe Pointer in der Struktur
   end;


Wenn ich das ganze Ausführe dann erhalte ich beim ersten Durchlauf "Test" dann denn Korrekten Namen des Objektes und vom Zeiger in der Struktur nur " ". Bei zweiten Druchlauf bekomme ich ebenfalls die ersten beiden korrekt angezeigt und vom Zeiger in der struktur erhalte ich diesmal eine Zugriffsverletzung.

hat jemand noch eine Idee dazu?

_________________
I need a girl whose name doesn't end in .JPG
gispos
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 94

WIN 7
XE10, D2007
BeitragVerfasst: Sa 08.12.07 22:19 
Also ich weiß wirklich nicht warum es bei Dir nicht klappt.
Habe gerade folgendes ohne Fehler getestet:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
type
  TTest= class
    FName: String;
  end;

procedure ETreeMouseDown(...);
var
  Node: PVirtualNode;
  Test: TTest;
  P: Pointer;
begin
  Node:= ETree_GetNodeAt(ETree,X,Y);
  If Assigned(Node) then
  begin
    ETree.NodeDataSize:= SizeOf(TTest);
    Test:= TTest.Create;
    P:= ETree.GetNodeData(Node);
    P:= @Test;
    Test.FName:= 'Bald ist Weihnachten';
    If Assigned(TTest(P^)) then
      ShowMessage(TTest(P^).FName);
    Test.Free;
  end;
end;


Versuche es bitte bei Dir, und gib bescheid
Gruß gispos

--- Moderiert von user profile iconNarses: Beiträge zusammengefasst ---

Nachtrag:
Habe noch dieses gefunden:
www.dsdt.info/tutori...tualtreeview/?page=3