Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi VST mit Objekten, Alle Nodes einer Spalte Durchlaufen (https://www.delphipraxis.net/66148-vst-mit-objekten-alle-nodes-einer-spalte-durchlaufen.html)

Metal_Snake2 25. Mär 2006 17:22


VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
 
Hallo,
Ich benutze die VST komponente mit objekte. Ich würde gerne alle nodes einer Spalte durchlaufen und deren in der VST angezeigten Text umändern.

Ich habe da leider keinen durchblick, normalerweise macht man das ja mit einer for schleife , nur hab ich leider keinen index mit dem ich einzelnt die Nodes ändern kann.

Meine zweite frage wäre noch wie ich soetwas soagar bei einer baumsturktur machen könnte.

thx

Der_Unwissende 25. Mär 2006 18:01

Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
 
Hi,
da ich die VST Komponente nicht habe, werde ich dir leider nicht direkt auf deine Frage antworten können. An sich ist es aber natürlich möglich alle Knoten eines Baumes zu besuchen. Man spricht dabei davon, dass man über den Baum traversiert.

Sehr einfach erklären lässt sich der Vorgang an einem Binärbaum (max. 2 Kindknoten). Natürlich gilt alles hier gesagt analog für jeden anderen Baum.
In der Regel ist bei einem Baum der Wurzelknoten bekannt. Dieser kennt wiederum all seine direkten Kinder. Eine Möglichkeit die du nun hast wäre es, den Wurzelknoten zu betrachten, ggf. irgendwas mit dem zu machen und dann rekursiv mit den beiden Kinderknoten weiter zu machen. Wichtig ist hier die Eigenschaft, dass jeder Kindknoten die Wurzel eines Teilbaums ist.
Z.B.
A <- Wurzel des gesamten Baums
B C <- Wurzel des Teilbaums C, F, G
D E F G <- Wurzel des Teilbaums G

Kommst du bei einem Blatt an, so erkennst du es daran, dass es keine Nachfolger / Kindknoten mehr gibt.
Je nachdem wie du durch den Baum traversierst, wirst du unterschiedlich schnell an einem bestimmten Knoten ankommen. Die eine Möglichkeit ist es, dass du dir einen Stack anlegst, auf dem du alle Kinder ablegst, die du für einen Teilbaum findest. Du betrachtest also einen Wurzelknoten, machst was du mit dem machen willst, packst alle Kinder auf den Stack und dann nimmst du das letzte Element vom Stack und betrachtest dieses nun als neuen Wurzelknoten (und gehst analog vor).
Hierbei würdest du dich der Tiefensuche bedienen. Das heißt du würdest jeden Zweig erst bis nach ganz unten laufen, bevor du den Geschwisterknoten betrachtest.
Wenn du statt einem Stack eine Queue benutzt, bei der du hinten anhängst, aber immer das erste Element entfernst, dann würdest du Breitensuche machen. Dass heißt (analog), dass du jede Zeile eines Baumes komplett durchläufst, bevor in einer Tieferen Zeile gesucht wird.
Natürlich kannst du auch den Wurzelknoten zu jedem Zeitpunkt betrachten, vor, nach oder zwischen den Kindknoten.
Aber ich denke dass sollte erstmal reichen.

Ach bevor ich es vergesse, eines möchte ich hier natürlich noch sagen. Du kannst Algorithmen auf Bäume zwar immer sehr leicht und elegant rekursiv erstellen, aber es geht genau so einfach iterativ. Statt einer For-Schleife eignet sich hier viel mehr eine while-Schleife. In dieser musst du nur schauen, ob es in deiner Liste (Queue oder Stack) noch mindestens ein Element gibt, wenn ja, dann ...
Zur Initialisierung muss natürlich nur das Wurzelelement des Baumes den du betrachtest in eben diese Liste.

Gruß Der Unwissende

Igotcha 25. Mär 2006 18:40

Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
 
Zitat:

Zitat von Metal_Snake2
Ich habe da leider keinen durchblick, normalerweise macht man das ja mit einer for schleife , nur hab ich leider keinen index mit dem ich einzelnt die Nodes ändern kann.

Da gibt es:

VST.Getfirst();
VST.GetNext(PVirtualNode);
VST.GetNextSibling(PVirtualNode);

Dann durchläufst Du den VST mit folgendem Code:

Delphi-Quellcode:
myNode:=VST.getfirst;
While Assigned(myNode) do
begin
   myData:=VST.GetNodeData(myNode);
   myData.xy:=was auch immer;
   myNode:=VST.GetNext(myNode);
   // oder s.o.
end;
So benutze ich das bei Records.

Gruß Igotcha

Metal_Snake2 25. Mär 2006 19:03

Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
 
Also ich habe folgendes definiert, im Interface teil:

Delphi-Quellcode:
type
  PTreeData = ^TTreeData;
  TTreeData = record
    FObject: TObject;
  end;

  TTreeDataClass = class
    private
      FProcName,
      FDomainAndUser,
      FTyp,
      FSecurtyLvl,
      FBasPrio,
      FLokalPath,
      FParentProc,
      FWinTitel,
      FFileProperty,
      FCompany,
      FStartTime,
      FMemUsage: WideString;
      FCpuUsage,
      FThreads,
      FPID,
      FParentID,
      FModules,
      FRunTime,
      FIconindex: Integer;
    published
      property ProcName: WideString read FProcName write FProcName;
      property DomainAndUser: WideString read FDomainAndUser write FDomainAndUser;
      property Typ: WideString read FTyp write FTyp;
      property SecurtyLvl: WideString read FSecurtyLvl write FSecurtyLvl;
      property BasPrio: WideString read FBasPrio write FBasPrio;
      property LokalPath: WideString read FLokalPath write FLokalPath;
      property ParentProc: WideString read FParentProc write FParentProc;
      property WinTitel: WideString read FWinTitel write FWinTitel;
      property FileProperty: WideString read FFileProperty write FFileProperty;
      property Company: WideString read FCompany write FCompany;
      property StartTime: WideString read FStartTime write FStartTime;
      property MemUsage: WideString read FMemUsage write FMemUsage;
      property CpuUsage: integer read FCpuUsage write FCpuUsage;
      property Threads: integer read FThreads write FThreads;
      property PID: integer read FPID write FPID;
      property ParentID: integer read FParentID write FParentID;
      property Modules: integer read FModules write FModules;
      property RunTime: integer read FRunTime write FRunTime;
      property Iconindex: integer read FIconindex write FIconindex;
    end;

Und mit dieser Funktion füge ich meien nodes hinzu:

function AddVSTStructure(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
  AObject: TObject): PVirtualNode;
var
  Data: PTreeData;
begin
  Result:=AVST.AddChild(ANode);
  Data:=AVST.GetNodeData(Result);
  AVST.ValidateNode(Result,False);
  data^.FObject := AObject;
end;
@Igotcha
Ich habe jetzt deinen code probiert jedoch funktioniert es nicht, so sieht jetzt mein Timer Ereignis aus:
Delphi-Quellcode:
procedure TForm1.ProcTimerTimer(Sender: TObject);
var
  TreeObject : TTreeDataClass;
  node      : PVirtualNode;
  Data      : PTreeData;
begin


  VST.BeginUpdate;
  Node := VST.getfirst;
  while Assigned(Node) do
  begin
    Node := VST.Getnodedata(Node);
    TTreeDataClass(Data.FObject).MemUsage:= 'hier der neu zugewiesener wert';
    VST.GetNext(Node);
  end;
  VST.EndUpdate;

end;
Was mache ich falsch?

[edit=sakura] [delphi]Tags Mfg, sakura[/edit]

Hawkeye219 25. Mär 2006 19:15

Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
 
Zwei kleine Fehler fallen mir spontan auf:

Dein Code
Delphi-Quellcode:
VST.BeginUpdate;
Node := VST.getfirst;
while Assigned(Node) do
begin
  Node := VST.Getnodedata(Node);
  TTreeDataClass(Data.FObject).MemUsage:= 'hier der neu zugewiesener wert';
  VST.GetNext(Node);
end;
VST.EndUpdate;
Richtig wäre:
Delphi-Quellcode:
VST.BeginUpdate;
Node := VST.getfirst;
while Assigned(Node) do
begin
  Data := VST.Getnodedata(Node); // <<<----- Fehler #1
  TTreeDataClass(Data.FObject).MemUsage:= 'hier der neu zugewiesener wert';
  Node := VST.GetNext(Node); // <<<----- Fehler #2
end;
VST.EndUpdate;
PS: So schön kann Code aussehen, wenn man die Delphi-Tags benutzt. :zwinker:

Gruß Hawkeye

Metal_Snake2 25. Mär 2006 19:32

Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
 
Es funktioniert!
vielen dank!

generic 27. Mär 2006 00:58

Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
 
mit vst.iteratesubtree geht das durchlaufen schneller.

Metal_Snake2 28. Mär 2006 21:20

Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
 
Sry das ich das Thema hier wieder neu zum leben erwachen lasse...aber ich komme wieder an einer stelle nicht weiter.

Also an meinen definitionen die ich hier(weiter oben) gepostet habe, hat sich nichts geändert.
Ich wollte fragen wie ich eine funktion wie AddVSTStructure(Siehe weiter oben im Thread) machen könnte die den genauen Index
eines Child Nodes benutze und das node (PVirtualNode) als rückgabe wert hat.

Die situation ist folgende struktur:

- RootNodeCount
+ Childcount
+ Childcount
+ Childcount
+ Childcount
+ Childcount

ich möchte halt zu einem Childcount genau eine neue Stuktur hinzufügen, falls auf das "plus"(Expandieren)" Symbol
des Childs geklickt wurde.

ich stelle mir das so for(Pseudocode):

Delphi-Quellcode:
function(i: integer):PVirtualNode;
begin

end;
wobei ich den Parameterwert also den index des Childnodex weis und angebe.
Wie mache ich das.
thx

Igotcha 28. Mär 2006 23:12

Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
 
Zitat:

Zitat von Metal_Snake2
wobei ich den Parameterwert also den index des Childnodex weis und angebe.
Wie mache ich das.
thx

Jaja, die Frage hatte wahrscheinlich jeder mal, der mit dem VST arbeit, die Lösung sieht eher "unglaublich" aus, funktioniert aber reibungslos und hochperformant:
Delphi-Quellcode:
function FindPLANNodeByGroupID(aTree: TBaseVirtualTree; gID: Integer): PVirtualNode;
var
   NodeData: pPlanData;
begin
   Result := aTree.GetFirst;
   while Assigned(Result) do
   begin
     NodeData := pPlanData(aTree.GetNodeData(Result));
     if NodeData^.FGroupid= gID Then
       Exit;
     Result := aTree.GetNext(Result);
   end;
end;
Angewandt wird das z.B. so (ich baue meine VSTs i.d.R. aus Datenbanken auf):
Delphi-Quellcode:
akt_Node:=atree.AddChild(FindPLANNodeByData(aTree, aQuery1.fieldbyname('pgid').asinteger));
myData:=atree.GetNodeData(akt_Node);
Mausklicks im VST wertet man folgendermaßen aus:
Delphi-Quellcode:
procedure TFProjektbericht.VTPROJEKTEMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  myHit: THitInfo;
begin
        VTPROJEKTE.GetHitTestInfoAt(x,y,true,myHit);
        if hiOnitem in myHit.HitPositions then
        begin
         mySelNode:=myHit.HitNode;
         if Assigned(mySelNode) then
         mySelData:=VTPROJEKTE.GetNodeData(mySelNode);
        end;
end;
Gruß Igotcha

Metal_Snake2 29. Mär 2006 00:12

Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke für die antwort.

Wie kann ich den jetzt z.B. herausfinden ob auf das "plus"(Expandier) Symbol geklickt wurde,
weil ich erst dan die neue struktur erzeugen möchte.

hmmm, irgendwie krieg ich dass jetzt immer noch nicht ganz gebacken.
Also mein Ereignis sieht jetzt so aus:

Delphi-Quellcode:
procedure TForm1.VSTClick(Sender: TObject);
var
  TreeObject      : TTreeDataClass;
  node,Childnode  : PVirtualNode;
  Data            : PTreeData;
  ME              : TModuleEntry32;
  hME             : THandle;
begin

           Vst.NodeDataSize:=SizeOf(TTreeData);
           Vst.BeginUpdate;

            try
              hME := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, (GetProcID('Explorer.exe')));
              ME.dwSize := sizeof(TModuleEntry32);
              Module32First(hMe, ME);
            repeat
              TreeObject := TTreeDataClass.Create;
              with TreeObject do
                begin
                  Modulename:=     ME.szModule;
                  ModulePath:=     ME.szExePath;
                  ProcUseCount:=   ME.ProccntUsage;
                  ModuleIconindex:= GetIconIndex(ME.szExePath, SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_OPENICON);

                  //Aus dem Modulenamen nur den typ beibehalten
                  ms:= ME.szModule;
                  ts:= Copy(ms,Pos('.',ms)+1,length(ms));

                  ModuleFileTyp:= ts;
              end;
              Childnode:= FindPLANNodeByGroupID(Vst,0); //Mit 0 mein ich ja das ich den ersten child node des rootnodes will
              AddVSTStructure(VST,Childnode:= ,TreeObject);
            until (not Module32Next(hMe, ME));
            CloseHandle(hME);
            Vst.EndUpdate;
         except
           TreeObject.free; //Object der Module
         end;

end;

////////// und in diesem ereignis möchte ich halt die einzelnen childnodes unterscheiden können, um den Text darstellen zu /////////  können

procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  Data: PTreeData;
begin
  Data := Sender.GetNodeData(Node);
      case Column of
        0: begin
             if (Sender.GetNodeLevel(Node) = 0) Then
               CellText := TTreeDataClass(Data.FObject).ProcName
             else if (Sender.GetNodeLevel(Node) = 1) Then
               CellText := TTreeDataClass(Data.FObject).FLevelHeader
             else if (Sender.GetNodeLevel(Node) = 2) and (Vst.ChildCount[Node] = 0) Then //Das funktioniert halt nicht
               CellText := TTreeDataClass(Data.FObject).Modulename
             else if (Sender.GetNodeLevel(Node) = 2) and (Vst.ChildCount[Node] = 1) Then
               CellText := TTreeDataClass(Data.FObject).FunktionsName
             else if (Sender.GetNodeLevel(Node) = 2) and (Vst.ChildCount[Node] = 2) Then
               CellText := TTreeDataClass(Data.FObject).Exportdll;
           end;
       end;
end;
Im Screenshot kann mans villeicht besser erkennen.
Die jeweiligen Childnodes die man sieht müßen noch geüllt werden. Sie sollen einzeln gefüllt werden wenn man auf das expandier symbol klickt, auf dem screen sieht man schon die colapsed situation jedoch sind die childnodes noch nicht geüllt.

kann man das machen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:09 Uhr.
Seite 1 von 2  1 2      

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