Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Finden einer Node (https://www.delphipraxis.net/14353-finden-einer-node.html)

CalganX 7. Jan 2004 15:59


Finden einer Node
 
Hi,
ich will mit Hilfe einer Funktion die oberste Node einer beliebigen SubNode finden. Was ich meine: ich habe eine Node, die sich einige Ebenen tiefer befinden, als die Hauptnode. Und diese Hauptnode will ich haben.
Also gehe ich immer weiter eine Ebene hoch, bis ich zu der entsprechenden Node kommen, deren Eigenschaft dwMode der Daten auf 1 steht.

So zumindest die Theorie. Die Praxis sieht folgendermaßen aus:
Delphi-Quellcode:
function TfrmMain.GetProjectNode(aNode: PVirtualNode): PVirtualNode;
var
  pNode: PVirtualNode;
  pData: PTVData;
begin
  pNode := aNode;
  Result := nil;
  while (true) do begin
    pData := vstData.GetNodeData(pNode);
    if (pData.dwMode = 1) or (pNode = nil) then Exit;
    pNode := pNode.Parent;
  end;
  Result := pNode;
end;
Doch da Delphi grundsätzlich eine Abneigung gegen mich hat meint er das CPU-Fenster öffnen zu müssen um stillschweigend zu sagen, dass ich böse war. ;)

Was mache ich falsch?

Chris

PS: Das ganze bezieht sich auf VirtualStringTree's. ;)

Chewie 7. Jan 2004 16:13

Re: Finden einer Node
 
Vielleicht solltest du noch abfragen, ob pData ungleich nil ist. Es könnte ja sein, dass eine Node keine Daten enthält.

CalganX 7. Jan 2004 16:15

Re: Finden einer Node
 
Hi Chewie,
ich denke, dass das nicht der Grund für den Fehler ist, zumal das nichts bringt und zum anderen ich immer die Daten selber schreibe und auch die Daten setze. ;)

Chris

Chewie 7. Jan 2004 16:18

Re: Finden einer Node
 
Geh trotzdem mal im Einzelschrittmodus durch, sowas kann nie schaden. Ist besonders nützlich bei Schleifen mit wenig Durchläufen ohne Rekursion und lange Berechnungen.

CalganX 7. Jan 2004 16:31

Re: Finden einer Node
 
Hi,
gute Idee. ;) Warum ich das immer vergessen?! :gruebel:

Jedenfalls hakt es an der markierten Zeile bzw. in der danach.
Code:
function TfrmMain.GetProjectNode(aNode: PVirtualNode): PVirtualNode;
var
  pNode: PVirtualNode;
  pData: PTVData;
begin
  pNode := aNode;
  Result := nil;
  while (true) do begin
    if (pNode = nil) then Exit;
[color=#ff0000]   pData := vstData.GetNodeData(pNode);[/color]
    if (pData = nil) then Exit;
    if (pData.dwMode = 1) then Break;
    pNode := pNode.Parent;
  end;
  Result := pNode;
end;
(Ja... das ist ein anderer Source, aber der oben war falsch)

Chris

CalganX 11. Jan 2004 10:46

Re: Finden einer Node
 
Hi,
hat denn keiner eine Idee, wo der Fehler sein kann? :(

Gibt es vielleicht eine andere Möglichkeit mein Vorhaben zu realisieren?

Chris

mirage228 11. Jan 2004 10:57

Re: Finden einer Node
 
Hi,

mit einem normalen TreeView habe ich es so gelöst. Bei meinem Test hat es sogar funktioniert :D

Delphi-Quellcode:
  function GetParentNode(Node: TTreeNode): TTreeNode;
  begin
    if Node.Level <> 0 then
    begin
      Node := Node.Parent;
      Result := GetParent(Node);
    end else Result := Node;
  end;
mfG
mirage228

CalganX 11. Jan 2004 11:16

Re: Finden einer Node
 
Hi,
danke, aber leider funktioniert das nicht. Das Problem ist, dass ich beim VST nur PVirtualNode verwenden kann und dieser Typ die Eigenschaft "Level" nicht hat und auch nicht vergleichbares. :(

Chris

CalganX 11. Jan 2004 12:10

Re: Finden einer Node
 
Hi,
es gibt doch eine Möglichkeit, aber leider funktioniert das auch nicht. :(

Chris

Jens Schumann 11. Jan 2004 12:31

Re: Finden einer Node
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
starte mal die Anlage und klicke auf einen beliebigen Node.
Dann schau Dir mal die function RootNodeText im Source an.

CalganX 11. Jan 2004 12:33

Re: Finden einer Node
 
Hi,
ich werde mir das gleich mal ansehen.

Habe aber den Fehler gefunden: ich habe das ganze auf Druck von F12 ausgelöst, aber gleichzeitig ist F12 ein Hotkey im VST. Jetzt geht es wunderbar. :-)

Danke,
Chris

CalganX 11. Jan 2004 12:42

Re: Finden einer Node
 
Hi Jens,
so geht es natürlich auch. :)
Habe es jetzt aber so ähnlich, wie mirage gemacht.

Aber jetzt gibt es ein anderes Problem:
ich versuche eine Listnode zu finden. Das ist eine Node, die sich eine "Etage" tiefer als das Projekt befindet. Das Problem ist, dass es von diesen Listnodes mehrere gibt. Alle haben eine andere Beschriftung. Ich habe mir dafür folgende Funktion gebastelt:
Delphi-Quellcode:
function TfrmMain.GetListNode(Node: PVirtualNode; Caption: String): PVirtualNode;
var
  pData: PTVData;
begin
  if vstData.GetNodeLevel(Node) = 1 then begin
    pData := vstData.GetNodeData(Node);
    if pData.szCaption = Caption then
      Result := Node  // <-- hier
    else
      GetListNode(Node.NextSibling, Caption);
  end else begin
    if vstData.GetNodeLevel(Node) < 1 then
      GetListNode(Node.FirstChild, Caption)
    else
      GetListNode(Node.Parent, Caption);
  end;
  Result := Node;
end;
Das Problem ist nun aber, dass auf die markierte Stelle durch den Compilier nie zugegriffen wird. Wieso? Und ist irgendwo ein Fehler? Denn es öffnet sich zwar nicht das CPU-Fenster, aber dafür scheint der Rückgabewert lt. Delphi nil zu sein. :?

Chris

Jens Schumann 11. Jan 2004 12:48

Re: Finden einer Node
 
Hallo,
wenn ich Dich richtig verstanden habe, möchtest Du ab einem bestimmten Node im
Baum abwärts suchen. Dann probier mal folgendes:
Delphi-Quellcode:
procedure TForm1.SearchLoop(Node: TTreeNode);
{SearchLoop geht von Node aus im Baum abwärts}
var
  TmpNode : TTreeNode;
begin
  If Node<>Nil then
    {Hier wird dann entschieden, ob der gesuchte Node gefunden wurde}
  TmpNode:=Node.getFirstChild;
  While TmpNode<>Nil do
    begin
     SearchLoop(TmpNode);
     TmpNode:=Node.getNextChild(TmpNode);
    end;
end;

CalganX 17. Jan 2004 19:49

Re: Finden einer Node
 
Hi,
ich habe das ganze mal auf das VST portiert und versucht das auf meinen Fall zu übertragen. Allerdings scheint das ganze eine endlosschleife zu sein. :(
Delphi-Quellcode:
function TfrmMain.SearchLoop(Node: PVirtualNode; sCaption: WideString): PVirtualNode;
var
  TmpNode : PVirtualNode;
  pData: PTVData;
begin
  If Node<>Nil then begin
    pData := vstData.GetNodeData(Node);
    if (pData <> nil) and (pData.szCaption = sCaption) then begin
      Result := Node;
      Exit;
    end;
  end else Result := nil;
  TmpNode:=Node.FirstChild;
  While TmpNode<>Nil do
    begin
     SearchLoop(TmpNode, sCaption);
     TmpNode:=Node.NextSibling;
    end;
end;
Chris

[edit]:gruebel: Ich weiß, dass ich was falsch gemacht habe. Und ich weiß auch, dass der Fehler darin liegt, dass ich den Rückgabewert von SearchLoop nicht behandel. Aber das Problem ist, dass ich nicht weiß, was ich tun soll. :cry:[/edit]

Jens Schumann 18. Jan 2004 15:22

Re: Finden einer Node
 
Hallo Chris,
stimmt, mein vorheriger Source klappert alle Unterknoten ab einem bestimmten Knoten
bis zum letzten Unterknoten ab.
Der Source hier funktioniert anders. Wähle einen bestimmten Knoten. Von diesem Knoten aus
werden alle Unterknoten besucht. Wenn ein Node mit dem gesuchten Text gefunden wurde bricht
die Rekursion ab.
Delphi-Quellcode:
function TForm1.SearchForNode(Node : TTreeNode; const NodeText : String) : TTreeNode;
var
  TmpNode : TTreeNode;
begin
  Result:=Nil;
  If Node<>Nil then
    If AnsiUpperCase(Node.Text)=AnsiUpperCase(NodeText) then
      Result:=Node;
  TmpNode:=Node.getFirstChild;
  While (TmpNode<>Nil) and (Result=Nil) do
    begin
     Result:=SearchForNode(TmpNode,NodeText);
     TmpNode:=Node.getNextChild(TmpNode);
    end;
end;
Ob das auch mit VirtualTreeView funktioniert kann ich sagen. Weil - habe ich nicht.

CalganX 18. Jan 2004 15:32

Re: Finden einer Node
 
Hi Jens,
vielen Dank! Das funktioniet wunderbar! Und das umschreiben auf VirtualStringTree hat auch wunderbar funktioniert.

Für alle interessierten: hier meine Funktion:
Delphi-Quellcode:
function TfrmMain.GetListNode(Node : PVirtualNode; const NodeText : String) : PVirtualNode;
var
  TmpNode : PVirtualNode;
  pData: PTVData;
begin
  Result:=Nil;
  If Node<>Nil then begin
    pData := vstData.GetNodeData(Node);
    If AnsiLowerCase(pData.szCaption)=AnsiLowerCase(NodeText) then
      Result:=Node;
  end;
  TmpNode:=Node.FirstChild;
  While (TmpNode<>Nil) and (Result=Nil) do
    begin
     Result:=GetListNode(TmpNode,NodeText);
     TmpNode:=Node.NextSibling;
    end;
end;
Das ist Jens' Code einfach nur auf VirtualStringTree übertragen.

Danke,
Chris


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:13 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