Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi VirtualStringTree: Nicht immer wird alles aufgelistet (https://www.delphipraxis.net/99212-virtualstringtree-nicht-immer-wird-alles-aufgelistet.html)

Nils_13 8. Sep 2007 16:37


VirtualStringTree: Nicht immer wird alles aufgelistet
 
Hi,

das ist nun die hoffentlich letzte Frage zum VST. Wenn ich oft hintereinander ein Verzeichniss mit meinem Programm durchsuche, wird oft nicht viel (4-6 Einträge) aufgelistet. Am Suchverfahren liegt es nicht, da 1. ich es schon ziemlich oft benutzt habe und mir nie etwas in der Art aufgefallen ist 2. da die Scrollbar die gleiche Größe, wie bei korrekter Auflistung, hat.

Woran liegt das ? / Wie kann man das umgehen ?

DGL-luke 8. Sep 2007 16:43

Re: VirtualStringTree: Nicht immer, wird alles aufgelistet
 
tu doch erstmal n bisschen debuggen.

erstens mal packst du dir ne listbox unter das vtv und schreibst da das ergebnis deines suchverfahrens rein. wenn das korrekt ist und mit dem, was das vtv anzeig, nicht identisch ist, wissen wir, dass dein problem in der darstellung liegt.

Deine Probleme liegen dann höchstwahrscheinlich in der Behandlung von "OnInitNode" bzw. "OnInitChildren". Zeig mal deinen Code her.

Nils_13 8. Sep 2007 17:15

Re: VirtualStringTree: Nicht immer, wird alles aufgelistet
 
Die Listbox zeigte, dass es wirklich an der Darstellung liegt :) OnInitNode und OnInitChildren sind bei mir nicht zugewiesen, oder meinst du den Code aller gesetzten Ereignisse ? Falls ja:
Delphi-Quellcode:
procedure TfrmExp.VSTFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var Data : PTreeData;
begin
  Data := VST.GetNodeData(Node);
  if Assigned(Data) then
  begin
    Data.fCaption := '';
    Data.fGroesse := '';
    Data.fDateityp := '';
    Data.fIcon    := 0;
  end;
end;

procedure TfrmExp.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var Data: PTreeData;
begin
  Data := VST.GetNodeData(Node);
  case Column of
    0: CellText := Data.fCaption;
    1: CellText := Data.fGroesse;
    2: CellText := Data.fDateityp;
  end;
end;

procedure TfrmExp.VSTDblClick(Sender: TObject);
var Node : PVirtualNode;
    Data : PTreeData;
begin
  Node := VST.FocusedNode;
  if not Assigned(Node) then
    Exit;

  Data := VST.GetNodeData(Node);
  if Pfad[Length(Pfad)] <> '\' then
    Pfad := Pfad + '\';
  Search(Pfad + Data.fCaption);
end;

procedure TfrmExp.VSTGetImageIndex(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
  var Ghosted: Boolean; var ImageIndex: Integer);
var Data : PTreeData;
begin
  Data := VST.GetNodeData(Node);
  if Assigned(Data) then
    if Column = 0 then
      if Data.fTyp = (ftFile) then
        ImageIndex := Data.fIcon
      else
        ImageIndex := 0;
end;

procedure TfrmExp.VSTCompareNodes(Sender: TBaseVirtualTree; Node1,
  Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
var Data1, Data2 : PTreeData;
begin
  Data1 := Sender.GetNodeData(Node1);
  Data2 := Sender.GetNodeData(Node2);
  if (Data1.fTyp = Data2.fTyp) then
    Result := CompareText(Data1.fPfad, Data2.fPfad)
  else
    Result := Ord(Data2.fTyp = ftDir) - Ord(Data1.fTyp = ftDir);
end;
Und falls es noch hilft, hier die Suche, welche die Einträge direkt hinzufügt:
Delphi-Quellcode:
procedure CurDir(TimerID, Msg: Uint; dwUser, dw1, dw2: DWORD); pascal;
begin
  //frmMain.lCurDir.Caption := ST.CurrentDir;
  //frmMain.lTime.Caption  := IntToStr(St.SearchDuration)+' ms';
  //frmMain.lFiles.Caption := IntToStr(St.FilesCount);
  //frmMain.lDirs.Caption  := IntToStr(St.DirsCount);
end;

procedure TfrmExp.STStart(var Msg: TMessage);
begin
  VST.Clear;
  tid := TimeSetEvent(500, 1, @CurDir, 0, TIME_PERIODIC);
end;

procedure TfrmExp.STNewFile(var Msg: TMessage);
var TreeData : TTreeData;
    Ext     : String;
    Icon    : TIcon;
begin
  VST.NodeDataSize := SizeOf(TTreeData);
  VST.BeginUpdate;

  TreeData.fCaption := ExtractFileName(PWideChar(Msg.LParam));
  TreeData.fPfad    := PWideChar(Msg.LParam);
  TreeData.fGroesse := BytesToStr(GetFileSize(PWideChar(Msg.LParam)));
  TreeData.fTyp     := (ftFile);

  Ext := ExtractFileExt(TreeData.fCaption);
  if not (Pos('*.', Ext) > 0) then
  begin
    if Ext[1] = '.' then
      Ext := '*' + Ext
    else
      Ext := '*.' + Ext;
  end;
  if Ext <> '' then
  begin
    TreeData.fDateityp := GetExtDes(Ext, False);
    Icon := TIcon.Create;
    GetExtIcon(Ext, Icon, False);
    TreeData.fIcon := Img.AddIcon(Icon);
    Icon.Free;
  end;
  AddVSTStructure(VST, nil, TreeData);
  VST.EndUpdate;
end;

procedure TfrmExp.STNewDir(var Msg: TMessage);
var TreeData : TTreeData;
begin
  VST.NodeDataSize := SizeOf(TTreeData);
  VST.BeginUpdate;

  TreeData.fCaption := ExtractFileName(PWideChar(Msg.LParam));
  TreeData.fPfad    := PWideChar(Msg.LParam);
  TreeData.fGroesse := '';
  TreeData.fDateityp := 'Ordner';
  TreeData.fTyp     := (ftDir);

  AddVSTStructure(VST, nil, TreeData);
  VST.EndUpdate;
end;

procedure TfrmExp.STFinish(var Msg: TMessage);
begin
  Application.ProcessMessages;
  TimeKillEvent(tid);

  //frmMain.lCurDir.Caption := 'Fertig';
  //frmMain.lTime.Caption  := IntToStr(St.SearchDuration)+' ms';
  //frmMain.lFiles.Caption := IntToStr(St.FilesCount);
  //frmMain.lDirs.Caption  := IntToStr(St.DirsCount);
end;

C.Schoch 8. Sep 2007 21:58

Re: VirtualStringTree: Nicht immer, wird alles aufgelistet
 
Hi,

IMO sieht das ganz gut aus, kommt der Fehler nur sporadisch vor?

Zeig mal den Code zu:
Delphi-Quellcode:
AddVSTStructure(VST, nil, TreeData);

Nils_13 8. Sep 2007 22:07

Re: VirtualStringTree: Nicht immer wird alles aufgelistet
 
Jp, es kommt nur gelegentlich vor.

Delphi-Quellcode:
  TTyp     = (ftFile, ftDir);

  PTreeData = ^TTreeData;

  TTreeData = record
    fCaption : String;
    fPfad    : String;
    fGroesse : String;
    fDateityp : String;
    fIcon    : Integer;
    fTyp     : TTyp;
  end;

function AddVSTStructure(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
  ARecord: TTreeData): PVirtualNode;
var Data : PTreeData;
begin
  Result := AVST.AddChild(ANode);
  Data  := AVST.GetNodeData(Result);
  AVST.ValidateNode(Result, False);
  Data^.fCaption := ARecord.fCaption;
  Data^.fPfad    := ARecord.fPfad;
  Data^.fGroesse := ARecord.fGroesse;
  Data^.fDateityp := ARecord.fDateityp;
  Data^.fIcon    := ARecord.fIcon;
  Data^.fTyp     := ARecord.fTyp;
end;

C.Schoch 8. Sep 2007 22:30

Re: VirtualStringTree: Nicht immer wird alles aufgelistet
 
Sieht auch ganz gut aus

Ich hab momentan auch keine Idee mehr :gruebel:
Außer, warum weist du einen pWideChar auf einen String zu?

Nils_13 9. Sep 2007 09:05

Re: VirtualStringTree: Nicht immer wird alles aufgelistet
 
fCaption ist wegen ExtractFileName ein String, fPfad habe ich zu pWideChar verändert, aber das hat auch nichts geändert.

Prototypjack 9. Sep 2007 10:42

Re: VirtualStringTree: Nicht immer wird alles aufgelistet
 
Moin,

Da die NodeDataSize immer gleich bleibt, kannst du es vermeiden (imho solltest du es auch), diese immer neu zu setzen. Setze sie am besten in einem Ereignis von dem du weißt, dass es vor den Auflistungen einmal ausgeführt wird.

Da du in den beiden Proceduren sowieso nur ein Item hinzufügst, dürfte das BeginUpdate;/EndUpdate; auch herzlich umsonst sein.

Möglicherweise gibt es tatsächlich einen Fehler bei der Updateprocedure des Controls, denn schließlich wird es durch diese Events beeinflusst und multible Aufrufe könnten das Ding durcheinander bringen.

Naja, nur eine Überlegung ;)

Grüße,
Maxs

Nils_13 9. Sep 2007 16:57

Re: VirtualStringTree: Nicht immer wird alles aufgelistet
 
Die Überlegung ist nicht schlecht. Welches Ereigniss würde sich denn für "VST.NodeDataSize := SizeOf(TTreeData);" eignen ?

Prototypjack 9. Sep 2007 19:25

Re: VirtualStringTree: Nicht immer wird alles aufgelistet
 
Zitat:

Zitat von Nils_13
Die Überlegung ist nicht schlecht. Welches Ereigniss würde sich denn für "VST.NodeDataSize := SizeOf(TTreeData);" eignen ?

Am ehesten etwas, was nur einmal und vor allem anderen ausgeführt wird. Bei VCL-gestützten Forms empfehle ich die OnCreate-Procedure.

Grüße,
Max

(Du könntest es auch vor dem Add des ersten Items setzen und dann eine Boolesche Variable auf True setzen, die dann verhindert, dass es noch einmal gesetzt wird.)


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:12 Uhr.
Seite 1 von 2  1 2      

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