![]() |
Welche Auflösungen besitzt ein *.ico-File
Moin Moin ...
Ein *.ico-File kann ja Icons in in verschiedenen Auflösungen enthalten. Wie kann man abfragen, ob z.B. ein Icon in der Auflösung 48x48 darin enthalten ist. Da ich über diesem Thema schwer graue Haare bekommen habe, wäre ich über ein Beispiel sehr dankbar. :stupid: Für Eure Mühe besten Dank ... |
Re: Welche Auflösungen besitzt ein *.ico-File
Ich weis aber nicht, ob folgenes immer funktioniert.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var Icon : TIcon; begin Icon:= TIcon.Create; try if OpenPictureDialog1.Execute then begin if FileExists(OpenPictureDialog1.FileName) then begin Icon.loadfromfile(OpenPictureDialog1.FileName); Caption := 'Breite: '+ inttostr(Icon.width); Caption := Caption+ ' Höhe: '+ inttostr(Icon.Height); end; end; finally Icon.Free; end; end; |
Re: Welche Auflösungen besitzt ein *.ico-File
Hi ...
Nee, hift leider nicht, denn es wird immer 32x32 zurückgegeben, auch wenn das Icon höhere Auflösungen enthält. Ich glaube das muss über GetIconInfo ablaufen. Das Handle auf mein Icon in meiner gewünschten Auflösung bekomme ich so: (aus den 'Abgründen' des Internets) :P
Delphi-Quellcode:
Das funktioniert (leider) auch, wenn die entsprechende Datei kein Icon in meiner gewünschten Auflösung besitzt. Windows vergrößert das Icon dann und das möchte ich (in besserer Qualität) lieber selber machen.
function GethIcon(FileName: String; icoSize: Cardinal; icoIndex: integer = 0): Cardinal;
var DeskTopISF: IShellFolder; IExIcon: IExtractIcon; PathPidl: PItemIDList; hIconL, hIconS: HIcon; begin Result := 0; {this function uses the IExtractIcon to get an e.g. 48x48 icon Handle from a file that Has the Icon Bitmaps in it, like an Icon File (.ICO), an executable (.EXE) and a library (.DLL)} if SHGetDesktopFolder(DeskTopISF) <> NOERROR then Exit; PathPidl := nil; if DeskTopISF.GetUIObjectOf(0, 1, PathPidl, IID_IExtractIconA, nil, IExIcon) <> NOERROR then Exit; if (IExIcon.Extract(PChar(FileName), icoIndex, hIconL, hIconS, icoSize or (16 shl 16)) = NOERROR) and (hIconL <> 0) then Result := hIconL; DestroyIcon(hIconS); end; Hinterher geht das wohl nicht mehr, deshalb möchte ich irgendwie vorher erfragen ob z.B. ein 48x48-Icon enthalten ist und falls nicht, dann lese ich lieber das 32x32-Icon aus und vergrößere es selber (per gr32) Dankbar für jeden weitern Ansatz, grüßt ... |
Re: Welche Auflösungen besitzt ein *.ico-File
Liste der Anhänge anzeigen (Anzahl: 1)
So ...
Um das mal zu verdeutlichen ein Bild im Anhang 1. FireFox oben links: 48x48 im Icon vorhanden und korrekt angezeigt 2. FireFox oben rechts 32x32 ausgelesen und von mir auf 48x48 vergrößert 3. Halo-Icon unten links von Windows vergrößert :evil: 4. Halo-Icon unten rechts als 32x32 ausgelesen und von mir vergrößert Nummer 3 ist leider pixelig, weil die Auflösung im Icon nicht vorhanden ist und genau das möchte ich im Vorfeld abfangen und lieber über die GR32-Lib vergrößern, weil Nummer 4 in diesem Fall besser aussieht. |
Re: Welche Auflösungen besitzt ein *.ico-File
Liste der Anhänge anzeigen (Anzahl: 1)
Jetzt verstehe ich auch erst, was du eigentlich erreichen möchtest.
Zitat:
Eine Möglichkeit wäre, wenn du deine Icone als Bilder aus der Resource extrahiest. Was anderes macht Windows auch nicht. Du kannst ja mal die Suche benutzen um herrauszufinden, wie man Icon Resourcen auslesen kann. |
Re: Welche Auflösungen besitzt ein *.ico-File
Moin Moin ...
Das stimmt, was Du sagst und mir war bewust, das das Halo-Icon auch im entsprechenden 48x48 Format vorliegt. (vielleicht ein etwas unglückliches Beispiel) Meine Routine von oben hätte in diesem Falle auch das korrekte Icon herausgezogen. Aber: Wehe wenn eine Exe-Datei kein Icon im gewünschten Format besitzt ! Dann kommt es zu meinem Pixel-Effekt bei dem Windows, intern mit einer 'lausigen' Stretch-Routine das vergrößerte (nicht vorhandene) Icon zurückgibt. So ... weil ich meine, das die GR32-Truppe das besser kann, möchte ich vorher wissen, ob die Auflösung überhaupt in der Exe vorhanden ist. Die Idee mit dem Resourcen-Auslesen ist schon klar ... und zu diesem Thema habe ich auch schon kistenweise Routinen getestet, aber am Ende kommen sie immer mit einem von Windows gestreckten Icon um die Ecke ... :evil: Deshalb beeindruckt mich ja auch diese Mini-Routine von oben, welche ich nach ewig langer Suche im Internet gefunden habe. Diese 'frisst' praktisch alles was an Dateien daherkommt, ohne die 'LoadLibrary'-Befehle und einen Nachteil konnte ich bisher nicht feststellen. (unbedingt ein Tipp für die CodeLib !!!) Da das ursprüngliche Problem noch besteht bin ich für weitere Ideen immer sehr dankbar ... |
Re: Welche Auflösungen besitzt ein *.ico-File
Liste der Anhänge anzeigen (Anzahl: 1)
Moin,
mein Programm habe ich jetzt fertiggestellt, also dei den Dateien die ich getestet habe, hat es funktioniert. Kannst ja mal testen ob es zu gebrauchen ist. EDIT: einen Fehler behoben |
Re: Welche Auflösungen besitzt ein *.ico-File
Großartig so weit !!! Tolle Arbeit bitsetter. :thumb: Die Routine macht genau das, was ich alleine so nicht hinbekommen habe ... Besten Dank dafür ! Exe und Dll's klappen auf Anhieb. Bei reinen *.ico-Dateien ist das Programm leider immer der Meinung es gäbe keine 48x48-Icone. Haben die ein anderes Format ?
Schöne sonnige Tage, wünscht ... |
Re: Welche Auflösungen besitzt ein *.ico-File
Liste der Anhänge anzeigen (Anzahl: 1)
Schön, dass es bei dir funktioniert, ich werde heute nochmal sehen, ob man da was machen kann. Auf jeden Fall enthält ein Icon ja normalerweise keine Ressourcen, daher wird es nicht funktionieren.
EDIT: Jetzt habe ich noch ein Programm, dass feststellen kann ob in ".ico" Dateien Icone mit einer Auflösung von 48X48 (und auch andere Auflösungen) enthalten sind. Bei den von mir getesteten Iconen, hat es jedenfalls funktioniert. |
Re: Welche Auflösungen besitzt ein *.ico-File
Mit folgender Routine kann man prüfen, ob sich in *.ico- oder in PE- Dateien mit Ressourcen wie *.exe *.dll usw., sich Icone in einer bestimmten Auflösung befinden.
Die Funktion HasIcoSize() könnte man also vor der von SittingDuck gesendeten Routine aufrufen. Bei den von mir getesteten Dateien hat es bis jetzt funktioniert. Falls noch einer Fehler in der Funktion findet, dann kann er sich ja dazu äußern, ich werde diese dann beheben.
Delphi-Quellcode:
type
TResID = record ResInt: integer; ResString: AnsiString; isInteger: boolean; end; type PResID = ^TResID; function EnumResIcon(Module: THandle; resType: PChar; HasIconGroup: PBool): bool; stdcall; begin if resType = RT_GROUP_ICON then begin HasIconGroup^:= true; result:= false; end else result:= true; end; function EnumIconNames(Module: THandle; ResType, ResName: PChar; ResID: PResID): bool; stdcall; begin if integer(resName)< $FFFF then begin ResID^.ResInt:= integer(ResName); ResID^.isInteger:= true; end else begin SetString(ResID^.ResString, ResName, Length(ResName)); ResID^.isInteger:= false; end; result:= false; end; function HasIcoSize(IconPfad: AnsiString; IconSize: Byte): boolean; var IconNr, IconAnzahl: byte; Next: cardinal; IconStream: TFileStream; ResStream: TResourceStream; Buffer: array of byte; FileExt: AnsiString; Lib: THandle; HasIcons: LongBool; ResID: TResID; begin result:= false; if FileExists(IconPfad) then begin FileExt:= UpperCase(ExtractFileExt(IconPfad)); if (FileExt= '.ICO') or (FileExt= '.CUR') then begin IconStream:= TFileStream.Create(IconPfad, fmOpenRead); try if IconStream.Seek(4, soFromCurrent)= 4 then if IconStream.Read(IconAnzahl, 1)= 1 then if IconStream.Seek(0, soFromBeginning)= 0 then begin Next:= 6; setlength(Buffer, IconAnzahl* 16); if IconStream.Read(Buffer[0], length(Buffer))= Length(Buffer) then for IconNr:= 1 to IconAnzahl do begin if (Buffer[Next]= IconSize) and (Buffer[Next+ 1]= IconSize) then begin result:= true; break; end; inc(Next, 16); end; end; finally IconStream.Free; end; end else begin Lib:= LoadLibraryEx(PChar(IconPfad), 0, LOAD_LIBRARY_AS_DATAFILE); if Lib<> 0 then try HasIcons:= false; EnumResourceTypes(Lib, @EnumResIcon, integer(@HasIcons)); if HasIcons then begin EnumResourceNames(Lib, RT_GROUP_ICON, @EnumIconNames, integer(@ResID)); if ResID.isInteger then ResStream:= TResourceStream.CreateFromID(Lib, ResID.ResInt, RT_GROUP_ICON) else ResStream:= TResourceStream.Create(Lib, ResID.ResString, RT_GROUP_ICON); try IconAnzahl:= byte(pointer(cardinal(ResStream.Memory)+ 4)^); Next:= 6; for IconNr:= 1 to IconAnzahl do begin if (byte(pointer(cardinal(ResStream.Memory)+ Next)^)= IconSize) and (byte(pointer(cardinal(ResStream.Memory)+ Next+ 1)^)= IconSize) then begin result:= true; break; end; inc(Next, 14); end; finally ResStream.Free; end; end; finally windows.FreeLibrary(Lib); end; end; end; end; procedure TForm1.Button1Click(Sender: TObject); begin if OpenDialog1.execute then if HasIcoSize(OpenDialog1.FileName, 48)then Showmessage('Die Datei hat Icone mit mit einer Größe von 48 X 48') else Showmessage('Die Datei hat KEINE Icone mit mit einer Größe von 48 X 48') end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:03 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