Autor Beitrag
schitho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Mo 30.06.03 23:16 
Hi,


ich steh vor folgendem Problem:

Ich möchte ein kleines FTP-Programm schreiben, das 2 VirtualTreeViews verwendet:

Links sollen die Lokalen-Dateien und
rechts die Remote-Dateien angezeigt werden.

Die Anzeige soll in einer Baumstruktur erfolgen, in der neben dem Namen, die Dateigröße, das Datum auch noch der Dateityp und das Icon angezeigt werden soll.

Wie komm ich nun zu den Icons und den Dateitypen für die Lokalen- und die Remoten-Dateien. Ich weiß, dass ich über

ausblenden Delphi-Quelltext
1:
2:
3:
4:
if SHGetFileInfo(PChar(Filename), 0, Info, SizeOf(Info), SHGFI_TYPENAME) <> 0 then
  Result := Info.szTypeName
else
  Result := '';


den Typ auslesen könnte. Allerdings lese ich hier nur den Typ der gerade angezeigten Datei aus.

Am Remote-Server geht das aber wohl nicht. :(

Daher wäre meine Idee, dass ich zuerst alle Dateitypen und Icons lokal auslese (also auch solche die ich gar nicht anzeige) und aufgrund dieses "Wissens", dann die Typen und Icons auch Remote zuordne.

Habt Ihr eine Idee wie ich sowas realisieren könnte???? :?

Danke für Eure Hilfe

_________________
(Sorry! Leider ewiger Delphi-Neuling)
ErnestoChe
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 528

Win 2000 pro, CRUX 2.0
Delphi 6 Pers, Open K3
BeitragVerfasst: Di 01.07.03 08:58 
Hi,

schau mal hier nach. Da ist im ersten Post von mir Code dabei, wie man das mit den Datei-Icons macht.

MFG

- Ernesto -
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 01.07.03 11:29 
Remote wird es nicht gehen, da du nicht weißt mit was die Programme verknüft sind. Wahrscheinlioch mit nichts, da es wohl Windows-Anwendungen sind und es wahrscheinlich bei dir Windows-Anwendungen sein werden, es sich aber bei dem Server bei 90% um ein Linux-System handeln wird.
schitho Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Di 01.07.03 21:10 
Es ist mir klar, dass es Remote nicht geht.

Trotzdem such ich eine Möglichkeit alle Dateitypen mit den dazugehörigen Icons auszulesen.

Im Explorer kann man sich ja auch unter Extras|Ordneroption|Dateitypen alle Dateitypen inkl. Icons anzeigen lassen. Diese würde ich gern mit Delphi auslesen, so dass ich zu den jeweiligen Dateitypen Lokal und Remote die passenden Icons und Dateitypen anzeigen kann.

Wäre ja blöd, wenn ich Lokal und Remot ich andere Icons verwenden würde, bei den gleichen Dateitypen.

Habt Ihr eine Idee, wie ich nun diese Dateitypen auslesen kann?

_________________
(Sorry! Leider ewiger Delphi-Neuling)
schitho Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Di 01.07.03 23:48 
Ich glaub ich hab selbst die Lösung fast gefunden (durch intensives Stöbern im Internet) :D

Zuerst lese alle Icons in eine ImageListe:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.FormCreate(Sender: TObject);
var
  SysIL : uint;
  SFI : TSHFileInfo;
begin
  SysIL := SHGetFileInfo(''0, SFI, SizeOf(SFI), SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
  if SysIL <> 0 then begin
    SmallImages.Handle := SysIL;
    SmallImages.ShareImages := TRUE;
  end;
  Form1.VST.Images:=SmallImages;
end;


Dann ermittle ich mittels

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function GetIconIndex(const AFileName: string;
  Attrs: DWORD): integer;
var
  SFI : TSHFileInfo;
begin
  SHGetFileInfo(PChar(AFileName), Attrs, SFI, SizeOf(TShFileInfo),
                SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES);
  Result := SFI.iIcon;
end;


für die jeweilige Datei den Index.

Einziger Nachteil: Für Ordner bekomm ich so scheinbar kein Icon geliefert.

Daher meine Frage: Wie bekomm ich das Icon von einem Ordner???

_________________
(Sorry! Leider ewiger Delphi-Neuling)
ErnestoChe
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 528

Win 2000 pro, CRUX 2.0
Delphi 6 Pers, Open K3
BeitragVerfasst: Mi 02.07.03 09:16 
Hi,

hast Du meinen Post durchgelesen? Damit geht das.

MFG

- Ernesto -
schitho Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Mi 02.07.03 22:25 
Hi,

ähhhmm. Hab es schon gelesen, aber komm trotzdem nicht weiter. Oder ich seh den Wald vor lauter Bäume nicht :oops:

Ich gehe momentan wie folgt vor:


Ich lese alle Icons in eine ImageList ein:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.FormCreate(Sender: TObject);
var
  SysIL : uint;
  SFI : TSHFileInfo;
begin
  SysIL := SHGetFileInfo(''0, SFI, SizeOf(SFI), SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
  if SysIL <> 0 then begin
    SmallImages.Handle := SysIL;
    SmallImages.ShareImages := TRUE;
  end;  
  Form1.VST.Images:=SmallImages;
end;



Ich verwende eine Funktion zum Auslesen des IconIndex:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
function GetIconIndex(const AFileName: string; Attrs: DWORD): integer;
var
  SFI : TSHFileInfo;
begin
  SHGetFileInfo(PChar(AFileName), Attrs, SFI, SizeOf(TShFileInfo),
                SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES);
  Result := SFI.iIcon;
end;



und zum Auslesen des DateiTyps:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
function GetFileTyp(const AFileName: string): string;
var
  SFI : TSHFileInfo;
begin
    SHGetFileInfo(PChar(AFileName), 0, SFI, SizeOf(TShFileInfo),
         SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES);
    Result:= SFI.szTypeName
end;



Zum Einlesen des Verzeichnisses verwende ich folgende Prozedur:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure VerzeichnisEinlesen(VerzName, filter:string);
var 
    Info    : TSHFileInfo;
    SR      : TSearchRec;
    TreeData: TTreeData;
    Node : PVirtualNode;
begin
  if VerzName[length(VerzName)]<>'\' then
    VerzName:=VerzName+'\';
  if filter='' then filter:='*.*';
  with Form1 do begin
    VST.BeginUpdate;
    VST.Clear;
    VST.NodeDataSize:=SizeOf(TTreeData);
    if FindFirst(VerzName+filter,faAnyFile  ,SR)=0 then begin
      repeat
        if (length(SR.Name)>0and ((SR.Name <> '.'and (SR.Name <> '..')) then begin
          if (LowerCase(SR.Name)<>'desktop.ini'and (LowerCase(SR.Name)<>'recycled'then
          begin
            TreeData.FCaption:=SR.Name;
            TreeData.FColumn1:='Bild-Index ' + IntToStr(GetIconIndex(SR.Name,FILE_ATTRIBUTE_NORMAL ));
            TreeData.Image:=GetIconIndex(SR.Name,FILE_ATTRIBUTE_NORMAL );
            TreeData.Typ:= GetFileTyp(SR.Name);
            Node:=VST.FocusedNode;
            AddVSTStructure(VST,Node,TreeData);
          end
        end;
      until FindNext(SR)<>0;
      FindClose(SR);
    end;
    VST.EndUpdate;
  end;
end;


Vollständigkeitshalber sei noch erwähnt, dass ich die Komponenten VirtualTreeView verwende. Zum Hinzufügen der Nodes gibt es folgende Funktion:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
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^.FColumn1:=ARecord.FColumn1;
  Data^.Typ:=ARecord.Typ;
  Data^.Image:=ARecord.Image;
end;



Mit VerzeichnisEinlesen('c:','*.*') lese ich das Verzeichnis von c: ein.

Die Icons und Typen, werden für die Dateitypen richtig angezeigt. Allerdings erkennt er Ordner nicht richtig, da weder das richtige Icon noch der richtige Typ ermittelt wird.

Wie muss ich meinen Code ändern, dass auch Ordner richtig angezeigt werden?

_________________
(Sorry! Leider ewiger Delphi-Neuling)
schitho Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Mi 02.07.03 23:57 
Hab den Fehler selbst gefunden :P

Es lag an SHGFI_USEFILEATTRIBUTES :roll:

Nachdem ich dieses Attribut entfernt habe, hat er auch die Ordner angezeigt.

Der Nachteil darf natürlich auch nicht verschwiegen werden:

Durch SHGFI_USEFILEATTRIBUTES ist es möglich auch die Icons bzw. den Dateityp für nicht am PC vorhandene Dateien anzuzeigen. :roll:

Daher braucht man es nur, wenn man auch Dateien auf fremden Servern (z.B. FTP) anzeigen lassen möchte.

_________________
(Sorry! Leider ewiger Delphi-Neuling)
Tino
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: Do 03.07.03 08:57 
schitho hat folgendes geschrieben:
Durch SHGFI_USEFILEATTRIBUTES ist es möglich auch die Icons bzw. den Dateityp für nicht am PC vorhandene Dateien anzuzeigen.

Wie soll denn das bitte funktionieren? Wenn bei mir kein Delphi installiert wäre woher sollte dann mein Windows wissen vorfür die Dateiendung PAS steht und welches Icon dafür angezeigt werden soll?

Gruß
Tino
schitho Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Do 03.07.03 09:32 
Hi,

verwendest Du
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
function GetIconIndex(const AFileName: string; Attrs: DWORD): integer; 
var 
  SFI : TSHFileInfo; 
begin 
  SHGetFileInfo(PChar(AFileName), Attrs, SFI, SizeOf(TShFileInfo), 
                SHGFI_SYSICONINDEX); 
  Result := SFI.iIcon; 
end;


bekommst Du nur den Icon-Index, wenn es die Datei gibt.

Änderst Du die Funktion jedoch in

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
function GetIconIndex(const AFileName: string; Attrs: DWORD): integer; 
var 
  SFI : TSHFileInfo; 
begin 
  SHGetFileInfo(PChar(AFileName), Attrs, SFI, SizeOf(TShFileInfo), 
                SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES); 
  Result := SFI.iIcon; 
end;


bekommst Du auch den Index zurück, wenn die Datei gar nicht auf der Platte vorhanden ist. Das funktioniert natürlich nur dann, wenn auf dem Rechner der Dateityp verknüpft ist.

Bspw. bekommst Du auch ein Ergebnis, wenn Du als Dateiname 'nichtvorhanden.gif' übergibst, weil die Funktion anhand der Dateiendung 'gif' das Iconindex zurodnen kann.

Der Nachteil von SHGFI_USEFILEATTRIBUTES ist jedoch, dass er dann bei vorhandenen lokalen Ordnern diese nicht also solche erkennt, sondern glaubt, dass es sich um einen unbekannte Datei ohne Dateiendung handelt und daher nicht den richtigen Iconindex zurückliefert.

_________________
(Sorry! Leider ewiger Delphi-Neuling)
Tino
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: Do 03.07.03 09:58 
Ups, hab dich falsch verstanden.
schitho hat folgendes geschrieben:
Durch SHGFI_USEFILEATTRIBUTES ist es möglich auch die Icons bzw. den Dateityp für nicht am PC vorhandene Dateien anzuzeigen.

Ich hatte gedacht du hast [...]nicht am PC vorhandene Dateitypen[...] geschrieben. Sorry... mein Fehler!

Gruß
Tino