![]() |
Problem mit Shellicons...
Ich benutze folgende Funktion um an den ShellIconindex zu kommen:
Delphi-Quellcode:
Das funktioniert bei 99,9% aller Dateien wunderbar, nur z.B. bei *.htm Dateien wird das Defaulticon (unbekannte Datei) anstelle des korrekten Icons (wie im Explorer dargestellt) zurückgeliefert...
function TServer.GetShellIcon(FileName: string): integer;
var SHFileInfo: TSHFileInfo; begin Result := 0; //Falls ein Laufwerksbuchstabe übergeben wurde... if Length(FileName) = 1 then FileName := FileName + ':'; //Laufwerke sollten mit \ enden... if (Length(FileName) = 2) and (copy(FileName, length(FileName), 1) = ':') and (copy(FileName, length(FileName), 1) <> '\') then FileName := FileName + '\'; //Dateiino lesen... ShGetFileInfo(PChar(FileName), 1, SHFileInfo, SizeOf(TSHFileInfo), SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_ICON); //IconIndex liefern... Result := SHFileInfo.iIcon end; |
Hallo,
Delphi-Quellcode:
liefert bei mir "4" zurück, Deine Funktion liefert "0", ich kenne zwar den Index der Icons nicht, aber ich denke mal es dürfte stimmen.
SHGetFileInfo(pchar('*.htm'), FILE_ATTRIBUTE_NORMAL, sfi, sizeof(sfi),
SHGFI_ICON OR SHGFI_USEFILEATTRIBUTES); Ersetzte mal den 2. Parameter (Deine 1) durch FILE_ATTRIBUTE_NORMAL und es müßte klappen... GRUND (schlag nach bei ![]() Zitat:
|
Nein, das war's leider nicht...
![]() P.S. Der IconIndex ist dynamisch, d.h. er kann variieren und hängt vom Zeitpunkt des ersten Zugriffes auf das jeweilige Icon ab. Beim Zugriff wird die SystemImageList aktualisiert und das entspr. Icon an der nächsten freien Position eingefügt. |
Moin FriFra,
hast Du mal in der Registry nachgeschaut, wie htm registriert ist? (HKEY_CLASSES_ROOT\.htm, Standardwert, HKEY_CLASSES_ROOT\<der Standardwert von .htm>\DefaultIcon , Standardwert) |
Das hat damit nichts zu tun... ich hab das gleiche Phänomen auf 3 Rechnern mit XP Home, XP pro und Win 2003, unter NT4 funktioniert es...
Im Windows Explorer werden die Dateien auch korrekt angezeigt. Allerdings habe ich schon div. einschlägige Democodes von verschiedenen Seiten geladen... kein Beispiel kann *.htm-icons richtig anzeigen... |
Zitat:
MfG Florian :hi: |
Delphi-Quellcode:
zeigt bei mir das html Icon an, aber nur wenn bei FullPath auch ein vollständiger Dateiname (incl. Pfad) angegeben wurde, *.htm alleine reicht nicht.
var
SHFileInfo: TSHFileInfo; const FullPath = 'D:\Eigene Dateien\Internet\HTML\Startseite\startseite.htm'; begin SHGetFileInfo(FullPath, 0, SHFileInfo, SizeOf(SHFileInfo), SHGFI_ICON); Image1.Picture.Icon.Handle := SHFileInfo.hIcon; end; Zitat:
|
Zitat:
Delphi-Quellcode:
und mir danach die SystemImageListe mit
SHGetFileInfo(pchar('*.htm'), FILE_ATTRIBUTE_NORMAL, sfi, sizeof(sfi),
SHGFI_ICON OR SHGFI_USEFILEATTRIBUTES); showmessage(inttostr(sfi.iIcon));
Delphi-Quellcode:
hole ist das Html Icon an 5. Stelle = 4. Index.
PROCEDURE GetSystemImageList(ImageList: TImageList);
VAR res : Integer; shf : TSHFILEINFO; BEGIN res := SHGetFileInfo('', 0, shf, SizeOf(shf), SHGFI_SYSICONINDEX OR SHGFI_SMALLICON); ImageList.handle := Res; ImageList.ShareImages := True; END; -------------------------------- VAR I : Integer; ListItem : TListItem; BEGIN GetSystemImageList(Imagelist1); BEGIN WITH ListView1 DO BEGIN SmallImages := ImageList1; LargeImages := ImageList1; FOR I := 0 TO ImageList1.Count - 1 DO BEGIN ListItem := Items.Add; ListItem.ImageIndex := I; END; END; END; |
Zitat:
Grüsse, Daniel :hi: |
Der Code sieht etwas anders aus (s. Eröffnungspost)...
Ich ermittle lediglich den ImageIndex des Icons. OnCreate habe ich zwei ImageLists das handle der Large-, bzw. SmallIconlist zugewiesen. Beim Aufruf meiner Funktion wird dann nur bei Bedarf ein neues Imagge in die Imagelist eingefügt, bzw. der Index des schon vorhandenen Images geliegfert - eine andere Vorgenensweise (direkter Zugriff auf das Icon) ist nicht performant, bzw. mit keinem heutigem Rechner durchführbar, da die Ressourcen extrem schnell verbraucht wären... P.S.: Ich übergebe immer den kompletten Pfad exisistierender Dateien. Ja, ich meine den Server 2003 (hab ich im Keller stehen :dancer: ) |
Mann sollte im PSDK auch bis zum Ende lesen :oops:, das hier funktioniert aber auch:
Delphi-Quellcode:
var
SHFileInfo: TSHFileInfo; begin SHGetFileInfo('*.htm', FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_ARCHIVE, SHFileInfo, SizeOf(SHFileInfo), SHGFI_ICON or SHGFI_USEFILEATTRIBUTES); // Zeigt das Bild in einem TImage an Image1.Picture.Icon.Handle := SHFileInfo.hIcon; end; Zitat:
Soviel Spionage hat 2000 ja auch nicht betrieben. :mrgreen: |
@Marco Haffner: :evil: NOCHMAL ZUM MITSCHREIBEN: ICH SUCHE NICHT DAS ICON.HANDLE, SONDERN DEN INDEX (s. mein Code oben :idea: ).
Mit dem Iconhandle kann man NICHTS anfangen, wenn es um das Auflisten von 100.000en Dateien geht, da man dabei für jede Datei einen Eintrag in die ImageList speichern müsste.... Den Rechner möchte ich sehen, der auch nur 100.000 Images in einer ImageList verkraftet :evil: , und wie lange soll das dauern... P.S.: Man sollte die Frage auch bis zum Ende lesen :oops: ! |
Re: Problem mit Shellicons...
Hallo,
Zitat:
p.s. Das Du 100.000 Icons in Deiner Liste hast, hast Du uns allen ziemlich lange verschwiegen, sei das nächste mal bitte etwas präziser !! p.p.s. Und brülle bitte Marco nicht an, er versucht (genau wie ich) Dir nur zu helfen! |
Re: Problem mit Shellicons...
Zitat:
Ach ne. Festplatte ist fast voll. :| MfG Florian :hi: |
Re: Problem mit Shellicons...
Zitat:
Ich habe keine 100.000 Icons in meiner Liste, das hab ich auch nie behauptet! Ich hätte aber sehr schnell 100.000 Icons im meiner Liste wenn ich gem des Vorschlags von Maro immer das Handle ermitteln würde und das icon dann jewils selst in die Imagelist kopieren würde. Ich brülle, weil Marco mir wiederholt einen Code gepostet hat, welcher nicht den Iconindex, sondern das Icon.Handle liefert. Im übrigen bringt der code bei mir keine Änderung, da auch dieser nur das Defaulticon ![]() |
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
bei mir funkt der Code. Habe zu Hause XPHome. |
und bei mir eben nicht... nur unter NT...
was nun? |
Moin FriFra,
ich hab' mal im MSDN geschaut (Suchbegriff SHFILEINFO) Ist zwar nicht unmittelbar was zu dem Problem genannt, aber eventuell sind folgende Artikel dennoch was für Dich: ![]() ![]() Ein Ergebnis des 2. Artikels: Wenn man das Icon einer Dateiklasse haben will, muss .extension angeben, nicht *.extension. |
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ehrlich gesagt keine Ahnung was jetzt noch geht. Probiere mal meinen Code. Ansonsten, eine gute Nacht! :cat: |
Liste der Anhänge anzeigen (Anzahl: 1)
Vielen Dank für den Code, allerdings macht der das gleiche wie der Code den ich bereits verwende.
Hier kannst Du jetzt sehen, was bei mir passiert... Ich dachte schon hier spinnen alle, andauernd bekomme ich den gleichen nicht funktionierenden Code. Aber warum der gleich code woanders läuft begreif ich nicht... Hast Du auch ServicePack 1 installiert? |
Moin FriFra,
und wenn Du es mal mit .htm versuchst? |
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Du kannst Dir ja mal den Screenshot und den Code von APP ansehen und meinen Screenshot... Ich befürchte fast, das es mit dem XP-SP1 zusammenhängt... Wie gesagt, unter NT hab ich das Problem nicht... |
Moin FriFra,
nur zur Info: Ich hab' mir das Attachement von APP mal runtergeladen: Button1 -> geht (4) Button2 -> geht nicht (0) W2K SP2 |
Wie schon gesagt, unter XP scheint der Code nicht zuverlässig zu sein...
So siet es bei mir aus (XP Home und XP pro!): http://www.delphipraxis.net/download.php?id=1371 und so bei APP: http://www.delphipraxis.net/download.php?id=1369 Ich frage mich dabei nur, welche andere verborgene API-Funktion verwendet der Explorer, denn der kann diese Icons anzeigen... |
Moin FriFra,
Du könntest noch versuchen mal gezielt InitCommonControls bzw. InitCommonControlsEx aufzurufen. Die haben auch was mit den ImageListen zu tun. |
Hallo,
folgende Methode liefert mir unter Win200 immer das richtige ICON.
Delphi-Quellcode:
procedure GetAssociatedIconEx(const Filename : String; Icon : TIcon);
var SHFileInfo: TSHFileInfo; begin // CoInitialize has to be called before SHGetFileInfo (done by Delphi) FillChar(SHFileInfo, SizeOf(TSHFileInfo), 0); if (SHGetFileInfo(PChar(Filename), FILE_ATTRIBUTE_NORMAL, SHFileInfo, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or SHGFI_SMALLICON) <> 0) then // or SHGFI_LARGEICON, SHGFI_LINKOVERLAY, SHGFI_OPENICON, SHGFI_SELECTED try // get it Icon.Handle := CopyIcon(SHFileInfo.hIcon); finally // you are responsible for destroying the icon handle DestroyIcon(SHFileInfo.hIcon); end; end; Quelle: Nico Bendlin |
Zitat:
![]() Ausserdem machst Du ja im Prinzip das Gleiche wie alle anderen auch... |
Hast Du eigentlich meine Routine auch ausprobiert, eine neue Anwendung nur mit einem TImage drauf? Falls nein, dann solltest Du es mal probieren, wahrscheinlich wird auch da nichts angezeigt.
Habe gerade noch etwas herumgebastelt und festgestellt, das bei mir die psd (Photoshop) und mpeg-Icons nicht angezeigt werden, es wird immer eine 3 als Index zurückgeliefert, genauso wir für ico-Dateien. |
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
http://www.delphipraxis.net/download.php?id=1385
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Buttons, ExtCtrls, ShellAPI; type TForm1 = class(TForm) Image1: TImage; procedure FormCreate(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure GetAssociatedIconEx(const Filename : String; Icon : TIcon); var SHFileInfo: TSHFileInfo; begin // CoInitialize has to be called before SHGetFileInfo (done by Delphi) FillChar(SHFileInfo, SizeOf(TSHFileInfo), 0); if (SHGetFileInfo(PChar(Filename), FILE_ATTRIBUTE_NORMAL, SHFileInfo, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or SHGFI_SMALLICON) <> 0) then // or SHGFI_LARGEICON, SHGFI_LINKOVERLAY, SHGFI_OPENICON, SHGFI_SELECTED try // get it Icon.Handle := CopyIcon(SHFileInfo.hIcon); finally // you are responsible for destroying the icon handle DestroyIcon(SHFileInfo.hIcon); end; end; procedure TForm1.FormCreate(Sender: TObject); begin GetAssociatedIconEx('c:\test.htm',Image1.Picture.Icon); end; end. |
Zitat:
Aber da ich ja jetzt weiß wonach ich bei mir suchen muß... |
Moin FriFra, moin Marco,
ihr habt doch beide ein D7 Version. In der müsste es doch den TShellTreeView/TShellListView geben. Was zeigen denn die an? Sollte es gehen, könnt ihr dann ja mal in den Sourcen nachsehen (sollte bei der Pro/Enterprise ja dabei sein) wie es dort gemacht wird. Ich hab' die ShellShock Kompos und dort wird nicht mit dem Dateinamen sondern der ItemIDList gearbeitet. |
Mit TShellTreeView/TShellListView klappt es...
Aber ich werd im moment nicht ganz schlau daraus... wie kann ich diese Funktion aus TShellTreeView/TShellListView verwenden, wenn ich einen Dateinamen übergeben will?
Delphi-Quellcode:
function GetShellImage(PIDL: PItemIDList; Large, Open: Boolean): Integer;
var FileInfo: TSHFileInfo; Flags: Integer; begin Flags := SHGFI_PIDL or SHGFI_SYSICONINDEX; if Open then Flags := Flags or SHGFI_OPENICON; if Large then Flags := Flags or SHGFI_LARGEICON else Flags := Flags or SHGFI_SMALLICON; SHGetFileInfo(PChar(PIDL), 0, FileInfo, SizeOf(FileInfo), Flags); Result := FileInfo.iIcon; end; |
Moin FriFra,
mit der Methode ParseDisplayName des Interface IShellFolder sollte man eine ITEMIDLIST die zum Namen gehört erhalten. Gemacht hab' ich das allerdings noch nicht. |
Re: Problem mit Shellicons...
Moin FriFra,
jetzt hab' ich das mal gemacht:
Delphi-Quellcode:
Bei mir funzt es, aber das tat's ja auch schon vorher ;-)
// uses SHLOBJ,SHELLAPI;
var isfWork : IShellFolder; piidWork : PItemIdList; dwDummy : DWORD; fiWork : TSHFileInfo; wsWork : WideString; begin // Interface auf IShellLink holen SHGetDesktopFolder(isfWork); // Vielleicht geht auch nur die Extension wsWork := 'Pfad der Datei'; // Weil Borland ja bei Pointern immer var Parameter nimmt ist ein Dummy erforderlich dwDummy := 0; // ItemIdList des Pfades holen isfWork.ParseDisplayName(0,nil,PWideChar(wsWork),dwDummy,piidWork,dwDummy); // Und die Info abfragen SHGetFileInfo(PChar(piidWork),0,fiWork,SizeOf(fiWork),SHGFI_PIDL or SHGFI_ICON or SHGFI_SMALLICON); // fiIcon.iIcon enthält jetzt auch den Index in der SystemImageList, hIcon das Handle end; Ich weiss etwas spät :oops: |
Re: Problem mit Shellicons...
Leider funktioniert auch dieser Code nicht:
![]() Deinen Code habe ich wie folgt implementiert:
Delphi-Quellcode:
function TMain.GetShellIcon(FileName: string): integer;
var isfWork : IShellFolder; piidWork : PItemIdList; dwDummy : DWORD; fiWork : TSHFileInfo; wsWork : WideString; begin Result:=0; // Interface auf IShellLink holen SHGetDesktopFolder(isfWork); //Falls ein Laufwerksbuchstabe übergeben wurde... if Length(FileName) = 1 then FileName := FileName + ':'; //Laufwerke sollten mit \ enden... if (Length(FileName) = 2) and (copy(FileName, length(FileName), 1) = ':') and (copy(FileName, length(FileName), 1) <> '\') then FileName := FileName + '\'; // Dateiname; Vielleicht geht auch nur die Extension wsWork := FileName; // Weil Borland ja bei Pointern immer var Parameter nimmt ist ein Dummy erforderlich dwDummy := 0; // ItemIdList des Pfades holen isfWork.ParseDisplayName(0,nil,PWideChar(wsWork),dwDummy,piidWork,dwDummy); // Und die Info abfragen SHGetFileInfo(PChar(piidWork),0,fiWork,SizeOf(fiWork),SHGFI_PIDL or SHGFI_ICON or SHGFI_SMALLICON); // fiWork.iIcon enthält jetzt auch den Index in der SystemImageList, hIcon das Handle try //IconIndex liefern... Result := fiWork.iIcon finally // you are responsible for destroying the icon handle DestroyIcon(fiWork.hIcon); end; end; |
Re: Problem mit Shellicons...
Moin FriFra,
komisch. Das ist doch eigentlich genauso, wie der ShellTreeView es macht, und, wenn ich nicht irre, bei dem gings doch. Versuch mal SHGI_ICON gegen SHGFI_SYSICONINDEX zu tauschen. Du brauchst ja nur den Index. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:59 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-2025 by Thomas Breitkreuz