![]() |
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 |
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 |
Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
Zitat:
VST.Getfirst(); VST.GetNext(PVirtualNode); VST.GetNextSibling(PVirtualNode); Dann durchläufst Du den VST mit folgendem Code:
Delphi-Quellcode:
So benutze ich das bei Records.
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; Gruß Igotcha |
Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
Also ich habe folgendes definiert, im Interface teil:
Delphi-Quellcode:
@Igotcha
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; Ich habe jetzt deinen code probiert jedoch funktioniert es nicht, so sieht jetzt mein Timer Ereignis aus:
Delphi-Quellcode:
Was mache ich falsch?
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; [edit=sakura] [delphi]Tags Mfg, sakura[/edit] |
Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
Zwei kleine Fehler fallen mir spontan auf:
Dein Code
Delphi-Quellcode:
Richtig wäre:
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;
Delphi-Quellcode:
PS: So schön kann Code aussehen, wenn man die Delphi-Tags benutzt. :zwinker:
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; Gruß Hawkeye |
Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
Es funktioniert!
vielen dank! |
Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
mit vst.iteratesubtree geht das durchlaufen schneller.
|
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:
wobei ich den Parameterwert also den index des Childnodex weis und angebe.
function(i: integer):PVirtualNode;
begin end; Wie mache ich das. thx |
Re: VST mit Objekten, Alle Nodes einer Spalte Durchlaufen
Zitat:
Delphi-Quellcode:
Angewandt wird das z.B. so (ich baue meine VSTs i.d.R. aus Datenbanken auf):
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;
Delphi-Quellcode:
Mausklicks im VST wertet man folgendermaßen aus:
akt_Node:=atree.AddChild(FindPLANNodeByData(aTree, aQuery1.fieldbyname('pgid').asinteger));
myData:=atree.GetNodeData(akt_Node);
Delphi-Quellcode:
Gruß Igotcha
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; |
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:
Im Screenshot kann mans villeicht besser erkennen.
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; 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 14:02 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 by Thomas Breitkreuz