AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi DAten der Festplatte in ner Treeview anzeigen
Thema durchsuchen
Ansicht
Themen-Optionen

DAten der Festplatte in ner Treeview anzeigen

Ein Thema von Kruemel2oo2 · begonnen am 29. Jun 2004 · letzter Beitrag vom 16. Jul 2004
Antwort Antwort
Seite 3 von 4     123 4      
MathiasSimmack
(Gast)

n/a Beiträge
 
#21

Re: DAten der Festplatte in ner Treeview anzeigen

  Alt 30. Jun 2004, 14:08
Wie wäre es denn, wenn du einfach mal den Suchlinks in den letzten Beiträgen folgst. Damit solltest du zuerst mal die Grundlagen zum "Scannen" der Ordner und Dateien haben.
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#22

Re: DAten der Festplatte in ner Treeview anzeigen

  Alt 30. Jun 2004, 14:10
Moin!

Ok, Zusammenfassung:

1. Definere dir eine Procedure die einen Knoten (TTreeNode) annimmt, bei dem werden dann die gefundenen Einträge eingehängt.
2. Definiere als weiteres in der Procedure einen Parameter für den Pfad in dem die Procedure suchen soll.
3. Der Inhalt der Procedure besteht dann zum Grossteil aus einer Schleife die mit FindFirst(), FindNext() und FindClose() das Verzeichnis ausliest was ihm übergeben wurde.
4. Bei einem gefundenen Eintrag:

4a) Wenn es ein Verzeichnis ist und dies nicht . oder .. ist, dann füge einen Knoten an den übergebenen Knoten als Child an (AddChild) und gebe ihm den Namen des Verzeichnis. Danach rufst du deine Funktion einfach wieder auf, nur du übergibst ihn den aktuell erstellten Knoten und den aktuellen Pfad mit dem gefundenen Verzeichnisnamen hinten dranne. (die Rekursion)
4b) Wenn es eine Datei ist, dann hänge einen neuen Knoten an den übergebenen Knoten an (AddChild) und gebe ihm den Namen der Datei.

5. Rufe die gebaute Funktion auf, in dem du ihr für den Knoten ein Nil übergibst und als Pfad den Laufwerksbuchstaben den er durchsuchen soll mit einem angehängten ":\".

Alles weitere steht samt Beispiele in der Hilfe von Delphi. Dazu einfach mal bei FindFirst(), FindNext(), FindClose() schauen (dort ist ein komplettes Beispiel drinne) - dann noch TTreeView, TTreeNode.

MfG
Muetze1
  Mit Zitat antworten Zitat
Kruemel2oo2

Registriert seit: 23. Jun 2004
65 Beiträge
 
#23

Re: DAten der Festplatte in ner Treeview anzeigen

  Alt 30. Jun 2004, 15:33
ok danke erstmal ich weerde es versuchen hinzubekommen
Alle Tippfehler dienen nur zur Belustigung und wurden mit voller Absicht gesetzt.


:-:-: [ich bin ein DAU ]:-:-:
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#24

Re: DAten der Festplatte in ner Treeview anzeigen

  Alt 30. Jun 2004, 16:49
Ich habe mal ein VCL-Beispiel für den Shell-Weg geschrieben. Das funktioniert nicht mit "FindFirst" (wenn du deinem Lehrer glaubhaft versichern kannst, dass das von dir ist, dann nimm´s für deine Schulaufgabe, @Kruemel2oo2, ). Wir brauchen eine Form mit einem Tree-View, der den Namen "tv" bekommt. Im "OnCreate"-Ereignis der Form wird die System-Imageliste an den Tree-View übergeben:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
  fi : TSHFileInfo;
  hSmallImg : HIMAGELIST;
begin
  ZeroMemory(@fi,sizeof(TSHFileInfo));
  hSmallImg := HIMAGELIST(SHGetFileInfo('',0,fi,sizeof(fi),
    SHGFI_SYSICONINDEX or SHGFI_SMALLICON));
  if(hSmallImg <> 0) then
    TreeView_SetImageList(tv.Handle,hSmallImg,TVSIL_NORMAL);

  self.FillTV;
end;
Die (private) Prozedur "FillTV" folgt auf dem Fuße. Die Sortierfunktion stammt aus der Delphi-Hilfe, ich habe bloß das Minus vor "AnsiStrIComp" weggelassen:
Delphi-Quellcode:
function TVSort(Node1, Node2: TTreeNode; Data: Integer): Integer; stdcall;
begin
  Result := AnsiStrIComp(PChar(Node1.Text),PChar(Node2.Text));
end;

procedure TForm1.FillTV;

  function CreateTreeNode(const iDesktopFolder: IShellFolder;
    hParent: TTreeNode; pidlNode: PItemIdList): TTreeNode;
  var
    szCaption : string;
  begin
    // der Name, wie man ihn aus dem Explorer kennt, ...
    szCaption := GetDisplayName(iDesktopFolder,pidlNode);
    // wer den kompletten Pfad sehen will (ein Vorteil bei der
    // Shell-Methode), der hängt als dritten Parameter die
    // beiden Flags
    // SHGDN_NORMAL or SHGDN_FORPARSING
    // an. :o)


    // Knoten erzeugen
    if(hParent = nil) then
      Result := tv.Items.AddFirst(nil,szCaption)
    else
      Result := tv.Items.AddChild(hParent,szCaption);
    Result.ImageIndex := GetShellImg(iDesktopFolder,pidlNode,false);
    Result.SelectedIndex := GetShellImg(iDesktopFolder,pidlNode,true);
  end;

  procedure Scan(const hParent: TTreeNode; iRootFolder: IShellFolder;
    pidlParent: PItemIdList; pMalloc: IMalloc);
  var
    tn : TTreeNode;
    iFolder : IShellFolder;
    ppEnum : IEnumIdList;
    hr : HRESULT;
    pidlItem : PItemIdList;
    uAttr,
    celtFetched : ULONG;
  begin
    // an ein untergeordnetes "IShellFolder"-Interface binden, ...
    if(iRootFolder.BindToObject(pidlParent,nil,IID_IShellFolder,
      iFolder) = S_OK) then
    begin
    // ... & die Enumerierung starten
      if(iFolder.EnumObjects(0,SHCONTF_FOLDERS or SHCONTF_INCLUDEHIDDEN,
        ppEnum) = S_OK) then
      begin
        hr := ppEnum.Next(1,pidlItem,celtFetched);
        while(hr = S_OK) and (celtFetched = 1) do
        begin
          // Knoten erzeugen
          tn := CreateTreeNode(iFolder,hParent,pidlItem);

          // wenn das aktuelle Element ein Ordner ist,
          // dann diese Prozedur erneut aufrufen und
          // den Ordner scannen lassen
          iFolder.GetAttributesOf(1,pidlItem,uAttr);
          if(uAttr and SFGAO_FOLDER <> 0) then
            Scan(tn,iFolder,pidlItem,pMalloc);

          // die benutzte "PItemIdList" freigeben, ...
          pMalloc.Free(pidlItem);
          pidlItem := nil;

          // ... & ab zum nächsten Element
          hr := ppEnum.Next(1,pidlItem,celtFetched);
        end;
      end;

      iFolder := nil;
    end;
  end;

var
  pMalloc : IMalloc;
  iDesktop : IShellFolder;
  pidlRoot : PItemIdList;
  tn : TTreeNode;
begin
  tv.Items.Clear;
  tv.Items.BeginUpdate;

  if(SHGetMalloc(pMalloc) = NOERROR) and
    (SHGetDesktopFolder(iDesktop) = NOERROR) then
  try
    // die "PItemIdList" des Laufwerks C:\ ermitteln
    GetIdFromPath(iDesktop,'c:\',pidlRoot);
    if(pidlRoot = nil) then exit;

    // Root einfügen, ...
    tn := CreateTreeNode(iDesktop,nil,pidlRoot);

    // ... & Laufwerk scannen, ...
    Scan(tn,iDesktop,pidlRoot,pMalloc);

    // "pidlRoot" freigeben
    if(pidlRoot <> nil) then pMalloc.Free(pidlRoot);
    pidlRoot := nil;
  finally
    pMalloc := nil;
    iDesktop := nil;
  end;

  tv.CustomSort(@TVSort,0);
  tv.Items[0].Expand(false);
  tv.Items.EndUpdate;
end;
Es fehlen noch ein paar Hilfsfunktionen, um bspw. den Namen für den Baum und das Symbol zu ermitteln:
Delphi-Quellcode:
function GetIdFromPath(const iDesktopFolder: IShellFolder; szPath: string;
  out pidl: PItemIdList): boolean;
var
  pchEaten,
  dwAttributes : dword;
  pcwPath : array[0..MAX_PATH]of widechar;
begin
  Result := false;
  if(iDesktopFolder <> nil) and
    (szPath <> '') then
  begin
    StringToWideChar(szPath,pcwPath,sizeof(pcwPath));
    iDesktopFolder.ParseDisplayName(0,nil,pcwPath,pchEaten,pidl,dwAttributes);
    Result := (pidl <> nil);
  end;
end;

function GetShellImg(const pidl: PItemIdList; fOpen: boolean): integer;
  overload;
var
  fi : TSHFileInfo;
  dwFlags : dword;
begin
  dwFlags := SHGFI_PIDL or SHGFI_SYSICONINDEX;
  if(fOpen) then dwFlags := dwFlags or SHGFI_OPENICON;

  SHGetFileInfo(pchar(pidl),0,fi,sizeof(fi),dwFlags);
  Result := fi.iIcon;
end;

function GetShellImg(const iDesktop: IShellFolder; pidl: PItemIdList;
  fOpen: boolean): integer; overload;
var
  isi : IShellIcon;
  uFlags : uint;
begin
  if(iDesktop.QueryInterface(IID_IShellIcon,isi) = S_OK) then
  begin
    if(fOpen) then uFlags := GIL_OPENICON
      else uFlags := 0;

    if(isi.GetIconOf(pidl,uFlags,Result) <> NOERROR) then
      Result := GetShellImg(pidl,fOpen);

    if(isi <> nil) then isi := nil;
  end
  else
    Result := GetShellImg(pidl,fOpen);
end;

function GetDisplayName(const iDesktop: IShellFolder; pidl: PItemIdList;
  dwFlags: dword = SHGDN_NORMAL): string;
var
  StrRet : TStrRet;
  p : pchar;
begin
  Result := '';
  iDesktop.GetDisplayNameOf(pidl,dwFlags,StrRet);

  case StrRet.uType of
    STRRET_CSTR:
      SetString(Result,StrRet.cStr,lstrlen(StrRet.cStr));
    STRRET_OFFSET:
      begin
        p := @PIDL.mkid.abID[StrRet.uOffset - sizeof(PIDL.mkid.cb)];
        SetString(Result,p,PIDL.mkid.cb - StrRet.uOffset);
      end;
    STRRET_WSTR:
      if(StrRet.pOleStr <> nil) then
        Result := StrRet.pOleStr
  end;
end;
Die Funktion "GetShellImg" ist überladen, weil ich anfangs ein Problem mit dem Symbol von "Eigene Dateien" hatte. Zurückgeliefert wurde mir das "Unbekannte Datei"-Icon (das leere Blatt mit dem Win-Symbol). Ursache war, warum auch immer?, die Verwendung der "PItemIdList". Wenn ich stattdessen den kompletten Pfad benutzt habe, sah ich zwar das richtige Symbol, allerdings brach die Performance ein.
Dank neolithos (meinen herzlichsten Dank nochmals! ) hat sich das Icon-Problem erledigt. Er verwies mich auf das IShellIcon-Interface, das ich in der zweiten Variante von "GetShellImg" benutzt habe. Die Scan-Performance blieb in dem Fall annehmbar, und die Symbole stimmten auch.

Hinweis: Ich habe erst seit dem Wochenende an diesen Interfaces gesessen. Es ist also keineswegs der optimalste Weg. Ich denke, man kann da noch mehr Geschwindigkeit rausholen, denn wenn ich bspw. meine XP-Partition K:\ scannen lasse, dauert das schon recht lange. Wenn ich dagegen an den Windows-Explorer denke, ... ... dann weiß ich, dass bei mir noch irgendwo der Pferdefuß steckt ...
Wer also Optimierungen beisteuern kann und will, der ist von meiner Seite aus sehr gern gesehen. Mich interessiert das nämlich.


Ach ja: Gebraucht werden die Units:
Delphi-Quellcode:
uses
  ShellAPI, ShlObj, ActiveX, CommCtrl;
und
Delphi-Quellcode:
initialization
  CoInitialize(nil);
finalization
  CoUninitialize;
end.
sollte auch angegeben werden.
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#25

Re: DAten der Festplatte in ner Treeview anzeigen

  Alt 30. Jun 2004, 18:30
Moin Mathias,

Zitat von MathiasSimmack:
...wenn ich bspw. meine XP-Partition K:\ scannen lasse, dauert das schon recht lange. Wenn ich dagegen an den Windows-Explorer denke,
Kannst Du mir mal ein Beispiel wann der Explorer die ganze Platte scannt?
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Kruemel2oo2

Registriert seit: 23. Jun 2004
65 Beiträge
 
#26

Re: DAten der Festplatte in ner Treeview anzeigen

  Alt 30. Jun 2004, 19:15
ooohaa also wenn ich mir das so anguck kann ich dazu nur sagen net schelcht aba ich werde es nie schaffen diesen Quelltext zu erklären hab ihn zwar nur grob überflogen aba so richtig raff ich da ja ent alles und das will ich ja . Aba ich bedanke mich das du mir deinen so einfach angeboten hast ;D.

Also mit dem Findfirst, FindNext und Findclose komm ich einigermasen klar also ich hab da son tuturial gefunden wo dies beschrieben ist. Aba die ausgabe ist in einem Memo feld. Naja nun wollte ich mich an diesen TTreeNode ran machen aba ich habe dazu net wirklich was gefunden zumindestens nischt womit ich was anfangen kann! Ich würd mich frauen wenn mir das ma einer so erklären könnte wie das funzen soll!
Alle Tippfehler dienen nur zur Belustigung und wurden mit voller Absicht gesetzt.


:-:-: [ich bin ein DAU ]:-:-:
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#27

Re: DAten der Festplatte in ner Treeview anzeigen

  Alt 30. Jun 2004, 19:41
Zitat von Christian Seehase:
Kannst Du mir mal ein Beispiel wann der Explorer die ganze Platte scannt?
Das weiß ich ja eben nicht. Wenn ich den Explorer starte, dann dauert es max. 2 Sekunden (und das ist schon lange!) bevor er erscheint. Und dann hast du sofort Zugriff auf die einzelnen Partitionen. Es wäre natürlich möglich, dass dieses Scannen bereits beim Starten von Windows in irgendeiner Form passiert, und dass der Explorer einfach darauf zugreift.

Das erklärt aber nicht, warum bspw. die ShellShock-Komponenten ebenfalls recht flink sind. Na ja, evtl. muss ich mich mal durch deren Quelltext wühlen. Reingeschaut habe ich ja schon, aber da die auf VCL-Komponenten basieren, wird das vermutlich ein Haufen Arbeit werden, die relevanten Teile herauszufinden.

Deswegen ja auch mein Posting. Wer Vereinfachungen und Optimierungen kennt, nur her damit. Notfalls muss der Beitrag eben geteilt werden, dann könnten wir unabhängig vom ursprünglichen Thema diskutieren.


@Kruemel: Nur überfliegen zählt nicht. Ausprobieren musst du ihn mal.
  Mit Zitat antworten Zitat
Kruemel2oo2

Registriert seit: 23. Jun 2004
65 Beiträge
 
#28

Re: DAten der Festplatte in ner Treeview anzeigen

  Alt 30. Jun 2004, 19:45
jo kann ich machen aba verstehen werd ich ihn denn wohl net viel mehr .
Alle Tippfehler dienen nur zur Belustigung und wurden mit voller Absicht gesetzt.


:-:-: [ich bin ein DAU ]:-:-:
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#29

Re: DAten der Festplatte in ner Treeview anzeigen

  Alt 30. Jun 2004, 19:51
Echt? Und ich habe mir extra Mühe beim Kommentieren gegeben.

Aber ernsthaft -
Du kannst es dann ja mal mit der FindFirst-Version vergleichen. Ich weiß zwar aus dem Kopf gerade nicht wieviele Ordner und Dateien auf meiner C-Partition stecken, aber o.g. Lösung über die Shell benötigt bei mir beim allerersten Mal (nach einem Neustart o.ä.) ~3sec, und dann im Schnitt nur noch 300-400msec.
Die FindFirst-Version dagegen braucht beim ersten Mal ... *puh* ... keine Ahnung, und dann so im Schnitt 1.5sec. Sie ist also bei mir stets langsamer.

Da aber der Explorer bzw. die erwähnten VCL-Komponenten alle Partitionen in einer kürzeren Zeit scannen, ist in meinem Code noch irgendwo eine Bremse drin. Wie gesagt, wenn ich mal Muße habe, dann nehme ich mal den ShellShock-Code auseinander.
  Mit Zitat antworten Zitat
Kruemel2oo2

Registriert seit: 23. Jun 2004
65 Beiträge
 
#30

Re: DAten der Festplatte in ner Treeview anzeigen

  Alt 30. Jun 2004, 19:54
em bekomme 3 Fehler von undefinierten typen .

GetDisplayName
GetShellImg
GetIdFromPath

die findet er net
Alle Tippfehler dienen nur zur Belustigung und wurden mit voller Absicht gesetzt.


:-:-: [ich bin ein DAU ]:-:-:
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:37 Uhr.
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