Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi DAten der Festplatte in ner Treeview anzeigen (https://www.delphipraxis.net/24974-daten-der-festplatte-ner-treeview-anzeigen.html)

Kruemel2oo2 29. Jun 2004 10:45


DAten der Festplatte in ner Treeview anzeigen
 
Hallo

ich weiß leida net wo ich dies hier reinposten soll also mach ic hdas hier :D

Ich möchte in ner Treeview eine Ausgabe aller Ordner haben also so mit C:\ --> Programme --> Borland ...

Könnte mir da mal bitte einer helfen?

gruß Kruemel

Christian Seehase 29. Jun 2004 13:17

Re: DAten der Festplatte in ner Treeview anzeigen
 
Moin Kruemel,

an welcher Stelle hakt es denn?
Weisst Du nicht, wie Du die Dateien ermitteln sollst, oder wie Du sie einem Treeview hinzufügen sollst?

glkgereon 29. Jun 2004 13:18

Re: DAten der Festplatte in ner Treeview anzeigen
 
meinst du vielleicht ne ShellTreeView?

Kruemel2oo2 29. Jun 2004 13:58

Re: DAten der Festplatte in ner Treeview anzeigen
 
also ich habe ne aufgabe bekommen die ich net hinbekomme! Ich schreib die einfach mal hier rein!

Also:

"Es ist ein Beispielprogramm in Delphi zu schreiben in der alle Verzeichnisse einer Festplatte in einem Verzeichnisbaum dargestellt werden. Dabei soll der Verzeichnisbaum mit Hilfe eines Treeview selbst erstellt werden!"

Naja ich dachte erst geht leicht aba hab ehrlich gesagt kein schimmer wie das geht!

Wäre nett wenn ihr mir das ma erklären könntet also wie das geht

gruß Kruemel

Christian Seehase 29. Jun 2004 14:01

Re: DAten der Festplatte in ner Treeview anzeigen
 
Moin Kruemel,

womit immer noch nicht geklärt wäre, wo's hakt. ;-)

Such' hier doch mal nach Hier im Forum suchenTTreeView bzw. Hier im Forum suchenFindFirst evtl. gibt's auch was unter Hier im Forum suchenTTreeView FindFirst, oder aber, wie glkbkk vorschlug Hier im Forum suchenShellTreeView

Kruemel2oo2 29. Jun 2004 14:26

Re: DAten der Festplatte in ner Treeview anzeigen
 
Es hakt daran das ich kein blassen schimma wie ich das machen soll :(

Christian Seehase 29. Jun 2004 14:28

Re: DAten der Festplatte in ner Treeview anzeigen
 
Moin Kruemel,

schau Dir doch erst einmal die Suchergebnisse an ;-)

S2B 29. Jun 2004 14:33

Re: DAten der Festplatte in ner Treeview anzeigen
 
Du könntest auch noch mal in der Codelib schauen! :wink: findfirstfindfirst

glkgereon 29. Jun 2004 18:42

Re: DAten der Festplatte in ner Treeview anzeigen
 
das problem:

"Es ist ein Beispielprogramm in Delphi zu schreiben in der alle Verzeichnisse einer Festplatte in einem Verzeichnisbaum dargestellt werden. Dabei soll der Verzeichnisbaum mit Hilfe eines Treeview selbst erstellt werden!"

er soll es selbst erstellen mithilfe eines treeview -> Shelltreeview kannste komplett vergessen, es muss treeview sein, wahrscheinlich dann mit find next, oder?

guck ma in die unit wo die shelltreeview drinsteht, ma gucken wie borland das gelöst hat

neolithos 29. Jun 2004 18:51

Re: DAten der Festplatte in ner Treeview anzeigen
 
Vergiss den ShellTreeView, dass ist viel zu kompliziert.

Erstelle einfach eine Rekursive funktion die am Programmstart von der Wurzel aus alle Verzeichnisse sucht, und in den TreeView einfügt.

glkgereon 29. Jun 2004 18:56

Re: DAten der Festplatte in ner Treeview anzeigen
 
das musser dann wohl mit findfirst und findnext machen, oder?

macht delphi selber das anders?

MathiasSimmack 30. Jun 2004 07:22

Re: DAten der Festplatte in ner Treeview anzeigen
 
Zitat:

Zitat von neolithos
Vergiss den ShellTreeView, dass ist viel zu kompliziert.

Im Gegenteil, das ist die einfachste Variante, weil du damit a) die Anzeige des Explorers sehr gut "imitierst" und b) der Scan-Vorgang auch IMHO schneller ist als via FindFirst und Co.

Ich habe mal versucht, das ohne die VCL selbst zu machen. An sich nicht das Problem, allerdings bin ich dabei auf einige Merkwürdigkeiten gestoßen. Aber das gehört, glaube ich, nicht in diesen Beitrag. Darüber könnte/müsste man separat diskutieren.

Zitat:

Zitat von glkbkk
das musser dann wohl mit findfirst und findnext machen, oder?

Ja, aber die Suchergebnisse sind wohl mehr als ausreichend. ;)

Zitat:

macht delphi selber das anders?
Beim ShellTreeView wird Borland es wohl so machen wie Microsoft im Explorer. Ansonsten liegt´s eben am Entwickler, der die Scanroutine selbst schreiben muss.

Kruemel2oo2 30. Jun 2004 08:04

Re: DAten der Festplatte in ner Treeview anzeigen
 
hmm was denn nun besser also nen Kumpel von mir meinte auch ich sollte es mit Findfirst machen! Dieses Findfirst ist ne funktion die man auhc in der Hilfe findet oder?

neolithos 30. Jun 2004 09:28

Re: DAten der Festplatte in ner Treeview anzeigen
 
Zitat:

Zitat von MathiasSimmack
Im Gegenteil, das ist die einfachste Variante, weil du damit a) die Anzeige des Explorers sehr gut "imitierst" und b) der Scan-Vorgang auch IMHO schneller ist als via FindFirst und Co.

Ich weis nicht was du als einfach ansiehst, aber bei dem ShellTreeView muss ich sehr viel über Com, Windows, SysImgList und den TreeView wissen.

Und so wie ich das sehe, ist diese "nur" eine Aufgabe von einer "Schule". Also sollte man nicht mit dem Holzhammer darauf schlagen.

Übrigens, ich habe mal in Delphi eine ShellListView geschrieben, mit allen was Windows bietet. Bis ich deine sogenannten merkwürdigen raushatte, verging viel Zeit. :mrgreen:
Habe aber mal wieder viel über Windows gelernt.

Kruemel2oo2 30. Jun 2004 09:57

Re: DAten der Festplatte in ner Treeview anzeigen
 
also ist es mit Findfirst leichter?

MathiasSimmack 30. Jun 2004 11:49

Re: DAten der Festplatte in ner Treeview anzeigen
 
Zitat:

Zitat von neolithos
Ich weis nicht was du als einfach ansiehst, aber bei dem ShellTreeView muss ich sehr viel über Com, Windows, SysImgList und den TreeView wissen.

Ich bezog mich auf deine Aussage, denn im Prinzip musst du überhaupt nichts wissen. Du pappst den STV auf die Form, und fertig. ;) Aber für die Schule und die Aufgabe ist das nichts. Man kann´s aber auch auf die Weise selbst machen, und Ja: Dann muss man viel über die o.g. Dinge wissen.

Zitat:

Übrigens, ich habe mal in Delphi eine ShellListView geschrieben, mit allen was Windows bietet. Bis ich deine sogenannten merkwürdigen raushatte, verging viel Zeit. :mrgreen:
Habe aber mal wieder viel über Windows gelernt.
Kannst du das mal anhängen? Ich würde gern mal einen Blick wg. Vereinfachungen usw. werfen. Wahrscheinlich lösen sich dann auch meine Probleme. Oder evtl. geht´s auch via PM, wenn´s nicht jeder haben soll. ;)

neolithos 30. Jun 2004 12:00

Re: DAten der Festplatte in ner Treeview anzeigen
 
Noch ein Paar Tipp's für die Aufgabe:

Damit Performant wird benötigst eine funktion, die eine Verzeichnis auslist und in der erstem Unterverzeichnisebene prüfst ob es ein Verzeichnis gibt, damit das Plus an (dummy-Knoten anfügen) bzw. nicht angezeigt wird.

Wird nun ein Knoten geöffnet musst du prüfen ob dort ein Dummy-Knoten existiert.
JA -> Lösche Dummy-Knoten und füge für jenen die Verzeichnisse ein (selbe Funktion wie oben)
NEIN -> es muss nichts getan werden.


Für die Symbole würde ich in dem Fall eine eigene ImageList anlegen mit den 2 Ordner Symbolen und den Laufwerkssymbol.

Christian Seehase 30. Jun 2004 12:07

Re: DAten der Festplatte in ner Treeview anzeigen
 
Moin Neolithos,

Zitat:

Zitat von neolithos
benötigst eine funktion, die eine Verzeichnis auslist und in der erstem Unterverzeichnisebene prüfst ob es ein Verzeichnis gibt, damit das Plus an (dummy-Knoten anfügen) bzw. nicht angezeigt wird.

was noch nicht einmal Windows so macht, denn oft genug klickt man auf ein [+], und es verschwindet, weil das System "merkt", dass es keine weiteren Verzeichnisse mehr darunter gibt.

glkgereon 30. Jun 2004 12:11

Re: DAten der Festplatte in ner Treeview anzeigen
 
:wall: :wall: arghh NEIN er kann evben KEIN Shelltreeview nehmen:

ich zitiere nochmal die aufgabenstellung
Zitat:

"Es ist ein Beispielprogramm in Delphi zu schreiben in der alle Verzeichnisse einer Festplatte in einem Verzeichnisbaum dargestellt werden. Dabei soll der Verzeichnisbaum mit Hilfe eines Treeview selbst erstellt werden!"
:warn: es muss mithilfe eines treeviewe SELBST erstellt werden :warn:

er muss ein treeview nehmen und MUSS eine eigene procedure nehmen

Kruemel2oo2 30. Jun 2004 12:43

Re: DAten der Festplatte in ner Treeview anzeigen
 
also alles schön und gut was ihr mir hier alle sagt aba so wirklihc schlauer bin ich net geworden!! Ich mein das was glkbkk ist richtig ich muss den scheiß in ner Treeview machen!

erklärt mir das was ihr hier alle posted ma so für einen DAU :D

MathiasSimmack 30. Jun 2004 13:08

Re: DAten der Festplatte in ner Treeview anzeigen
 
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.

Muetze1 30. Jun 2004 13:10

Re: DAten der Festplatte in ner Treeview anzeigen
 
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

Kruemel2oo2 30. Jun 2004 14:33

Re: DAten der Festplatte in ner Treeview anzeigen
 
ok danke erstmal ich weerde es versuchen hinzubekommen :D

MathiasSimmack 30. Jun 2004 15:49

Re: DAten der Festplatte in ner Treeview anzeigen
 
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, :mrgreen:). 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! :thuimb:) 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, ... :oops: ... 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. :stupid:


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.

Christian Seehase 30. Jun 2004 17:30

Re: DAten der Festplatte in ner Treeview anzeigen
 
Moin Mathias,

Zitat:

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?

Kruemel2oo2 30. Jun 2004 18:15

Re: DAten der Festplatte in ner Treeview anzeigen
 
ooohaa also wenn ich mir das so anguck kann ich dazu nur sagen net schelcht :D 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 :D. 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!

MathiasSimmack 30. Jun 2004 18:41

Re: DAten der Festplatte in ner Treeview anzeigen
 
Zitat:

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. :)

Kruemel2oo2 30. Jun 2004 18:45

Re: DAten der Festplatte in ner Treeview anzeigen
 
jo kann ich machen aba verstehen werd ich ihn denn wohl net viel mehr :(.

MathiasSimmack 30. Jun 2004 18:51

Re: DAten der Festplatte in ner Treeview anzeigen
 
Echt? Und ich habe mir extra Mühe beim Kommentieren gegeben. :cry:

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. ;)

Kruemel2oo2 30. Jun 2004 18:54

Re: DAten der Festplatte in ner Treeview anzeigen
 
em bekomme 3 Fehler von undefinierten typen .

GetDisplayName
GetShellImg
GetIdFromPath

die findet er net

MathiasSimmack 30. Jun 2004 18:59

Re: DAten der Festplatte in ner Treeview anzeigen
 
*hüstel* Das sind die oben erwähnten
Zitat:

Hilfsfunktionen, um bspw. den Namen für den Baum und das Symbol zu ermitteln
Wenn du die in deinem Quelltext hast, aber möglicherweise hinter den Form-bezogenen Routinen, dann zieh sie nach vorn, also bspw:
Delphi-Quellcode:
unit bla;

{ ... }


implementation

function GetIdFromPath
{ bla bla bla }



procedure TForm1.FillTV;


end.
So sollte es aussehen, weil Delphi solche (nicht Form-bezogenen) Funktionen nur findet, wenn sie vor dem Aufruf deklariert sind.

Wenn du sie noch nicht in deinem Quelltext hattest, dann schäm dich! In dem Fall hast du den Code tatsächlich nur überflogen. :mrgreen:

neolithos 30. Jun 2004 18:59

Re: DAten der Festplatte in ner Treeview anzeigen
 
Ich muss hier mal was klarstellen.

Wenn der Explorer geöffnet wird, wird nicht die Festplatte oder sonstwas gescannt. Sondern es wird nur der Teil geladen, der gerade angezeigt wird.

Deswegen dauert auch das aufklappen eines Ordner's mit vielen Verzeichnen länger als mit nur einem.

Das vorgehen des Explorers ist ähnlich meines Postings (siehe weiter oben). So würde ich das auch mit FindFirst und FindNext erledigen.

Ich vermute mal das hinter dem IShellFolder auch nicht mehr steht, halt nur noch ein wenig komplexer.

Übrigens: FAT, EXT und NTFS wurden nicht gebaut um die ganze Platte mit einmal zu Scanner, dies ist nahwezu unmöglich bei heute 160 GB (davon vielleicht ca. 1,5 GB für die Verzeichnisstruktur, wenn sie voll ist)

Kruemel2oo2 30. Jun 2004 19:05

Re: DAten der Festplatte in ner Treeview anzeigen
 
jo jetzt funzt das :D dauert wirklihc bischen lange. muss mir denn ma anschauen :D (bringt zwar nischt aba egal :D)

em könnte mir denn ma einer das mit dem TTreeNode erklären. bitte :D

bin einfach zu dumm :(

MathiasSimmack 30. Jun 2004 20:41

Re: DAten der Festplatte in ner Treeview anzeigen
 
Zitat:

Zitat von Kruemel2oo2
jo jetzt funzt das :D dauert wirklihc bischen lange.

Nur beim ersten Mal. Bei jedem weiteren Versuch geht´s schneller.

Zitat:

em könnte mir denn ma einer das mit dem TTreeNode erklären. bitte :D
Was denn genau?

Zitat:

bin einfach zu dumm :(
Hm, und da meinst du, dass eine Erklärung noch was hilft. ;)

Kruemel2oo2 30. Jun 2004 21:54

Re: DAten der Festplatte in ner Treeview anzeigen
 
:D jo bin lernfähig :D

naja wie ich das anwenden muss also ich hab nen Quelltext in nen Tutorial gefunden wie ich schon gescrieben habe aba die ausgabe ist in ner Listbox und nun will ich versuchen das durch den TTTreeNode in nen Treeview zu machen also ich kann ja ma den quelltext zeigen!

Code:
procedure GetFilesInDirectory(Directory: String; const Mask: String;
                              List: TStrings;
                              WithSubDirs, ClearList: Boolean);

procedure ScanDir(const Directory: String);
var
  SR: TSearchRec;
begin
  if FindFirst(Directory + Mask, faAnyFile - faDirectory, SR) = 0 then try
    repeat
      List.Add(Directory + SR.Name)
    until FindNext(SR) <> 0;
  finally
    FindClose(SR);
  end;

  if WithSubDirs then begin
    if FindFirst(Directory + '*.*', faAnyFile, SR) = 0 then try
      repeat
        if (SR.Attr = faDirectory) and
           (SR.Name <> '.') and (SR.Name <> '..') then
          ScanDir(Directory + SR.Name + '\');
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
  end;
end;

begin
  List.BeginUpdate;
  try
    if ClearList then
      List.Clear;
    if Directory = '' then Exit;
    if Directory[Length(Directory)] <> '\' then
      Directory := Directory + '\';
    ScanDir(Directory);
  finally
    List.EndUpdate;
  end;
end;
hier durch button click die ausgabe

Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
  GetFilesInDirectory('C:\', '*.*', Listbox1.Items, True, True);
end;
naja und jetzt muss ich erstma raffen wie ich diesen TTTreeNode anwende um das nachern in ner Treeview auszugeben. und nu hoff ich das mir das einer ma so nen bischen erklären kann :D

scp 1. Jul 2004 00:59

Re: DAten der Festplatte in ner Treeview anzeigen
 
Zitat:

Zitat von Kruemel2oo2
naja und jetzt muss ich erstma raffen wie ich diesen TTTreeNode anwende um das nachern in ner Treeview auszugeben. und nu hoff ich das mir das einer ma so nen bischen erklären kann :D

Du brauchst dir eigentlich nur die Funktion CreateTreeNode von dem Beispiel auf Seite 2 angucken. Diese könntest du abändern, in dem du statt dieses PIDL parameters direkt einen string-paramter für den Text des Knotens verwendest, z.B.
Delphi-Quellcode:
  function CreateTreeNode(hParent: TTreeNode; szCaption : string): TTreeNode;
  begin
Dann musst du nur noch die ScanDir Funktion so umbauen, das sie den aktuellen unterordner und den aktuellen TTreenode als Parameter entgegenehmen kann, z.B.

Delphi-Quellcode:
procedure ScanDir(const Directory: String; const SubDirectory: String; curtn : TTreeNode);
 var
  SR: TSearchRec;
  tn : TTreeNode;
begin
  tn := CreateTreeNode(curtn, SubDirectory);
Weiter unten rufst du ScanDir dann z.B. so auf:
Delphi-Quellcode:
ScanDir(Directory + SR.Name + '\', SR.Name, tn);
Der erste Aufruf (noch weiter unten) sähe dann so aus:
Delphi-Quellcode:
ScanDir(Directory, Directory, nil);
CreateTreeNode erstellt dann beim ersten Aufruf mit tv.Items.AddFirst() den Hauptknoten, weil das TreeView ja noch leer ist und deshalb beim ersten aufruf nil angegeben wird, das es noch keinen ParentNone (übergeordneten Knoten) gibt.
Bei den folgenden Aufrufen wird dann tv.Items.AddChild() verwendet, weil du ihm mit tn den TreeNode des aktuellen Ordners übergibst, in dem er ja dann einen Unterknoten erstellen soll.

Kruemel2oo2 1. Jul 2004 16:24

Re: DAten der Festplatte in ner Treeview anzeigen
 
hmpf alles subba erklärt fetten dank an alle bekomme es zwar noch net hin aba naja bin halt zu dumm für dieses scheiß TreeView :wall: ... naja kann man nischt machen. Aba an alle riesen fetten dank für die versuchte hilfe.

gruß Kruemel

neolithos 1. Jul 2004 16:29

Re: DAten der Festplatte in ner Treeview anzeigen
 
[TROST]
Keine sorge alles muss klein beginnen!
Das klappt schon! Bloß immer dran bleiben!
[/TROST]

Tempel 15. Jul 2004 20:30

Re: DAten der Festplatte in ner Treeview anzeigen
 
Zitat:

Zitat von MathiasSimmack
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. ;)

Hallo Mathias,

danke für die Funktion, hat mir einiges an Sucharbeit erspart :-D

In deinem Code ist keine Bremse drin, du darfst nur nicht den ganzen Verzeichnisbaum auf einmal einlesen. Wenn du Scan nicht rekursiv aufrufts, sondern stattdessen "tn.HasChildren := true;" setzt, geht das einlesen fix. Nun must du nur noch beim Ereignis OnExpanding Scan aufrufen, wenn "TreeNode.Count = 0" ist. So wird der nächste Zweig erst erstellt, wenn man ihn öffnet.

Thomas

MathiasSimmack 16. Jul 2004 07:40

Re: DAten der Festplatte in ner Treeview anzeigen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke für die Aufmunterung. ;) Aber dann hätte ich noch einen besseren Vorschlag. Setze nicht einfach "HasChildren" auf true, sondern prüfe ob das überhaupt notwendig ist. Folgende Änderung im Code von "Scan" macht das:
Delphi-Quellcode:
          // wenn das aktuelle Element ein Ordner ist,
          // dann diese Prozedur erneut aufrufen und
          // den Ordner scannen lassen
          uAttr := SFGAO_CONTENTSMASK;
          iFolder.GetAttributesOf(1,pidlItem,uAttr);
          tn.HasChildren := (SFGAO_HASSUBFOLDER and uAttr <> 0);
:stupid:

Jetzt müsste man IMHO nur entweder den kompletten Pfad oder die PItemIdList des aktuellen Ordners im TTreeNode speichern (Stichwort: Data = pointer), dann kann man beim Anklicken eines Knotens die entsprechenden Unterordner laden. Denke ich ... :)


PS: Ich hänge einfach mal die nonVCL-Version ran, an der ich heute nebenbei gesessen habe. Es ist eine recht einfache Variante, die die jeweiligen IDs in einer Klasse speichert und jedem Knoten zuordnet. Daher geht das Scannen der Partition jetzt tatsächlich recht fix, und die Unterordner werden eigentlich erst beim Aufklappen "geladen". ;)


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