AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Welche Auflösungen besitzt ein *.ico-File
Thema durchsuchen
Ansicht
Themen-Optionen

Welche Auflösungen besitzt ein *.ico-File

Ein Thema von SittingDuck · begonnen am 15. Feb 2007 · letzter Beitrag vom 1. Jul 2012
Antwort Antwort
Seite 1 von 2  1 2      
SittingDuck

Registriert seit: 11. Jan 2006
Ort: Leverkusen
159 Beiträge
 
Delphi 2010 Professional
 
#1

Welche Auflösungen besitzt ein *.ico-File

  Alt 15. Feb 2007, 12:04
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.

Für Eure Mühe besten Dank ...
Ciao ... SittingDuck
iPhone Backup und mehr: iTwin v3.9 Beta ... Alternative Startleiste: Launcher v3.8 !
  Mit Zitat antworten Zitat
Benutzerbild von bitsetter
bitsetter

Registriert seit: 17. Jan 2007
1.169 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Welche Auflösungen besitzt ein *.ico-File

  Alt 15. Feb 2007, 12:43
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;
Gruß bitsetter
"Viele Wege führen nach Rom"
Wolfgang Mocker (geb. 1954), dt. Satiriker und Aphoristiker
  Mit Zitat antworten Zitat
SittingDuck

Registriert seit: 11. Jan 2006
Ort: Leverkusen
159 Beiträge
 
Delphi 2010 Professional
 
#3

Re: Welche Auflösungen besitzt ein *.ico-File

  Alt 15. Feb 2007, 13:07
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)

Delphi-Quellcode:
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;
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.
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 ...
Ciao ... SittingDuck
iPhone Backup und mehr: iTwin v3.9 Beta ... Alternative Startleiste: Launcher v3.8 !
  Mit Zitat antworten Zitat
SittingDuck

Registriert seit: 11. Jan 2006
Ort: Leverkusen
159 Beiträge
 
Delphi 2010 Professional
 
#4

Re: Welche Auflösungen besitzt ein *.ico-File

  Alt 15. Feb 2007, 13:36
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
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.
Miniaturansicht angehängter Grafiken
beispiel_200.png  
Ciao ... SittingDuck
iPhone Backup und mehr: iTwin v3.9 Beta ... Alternative Startleiste: Launcher v3.8 !
  Mit Zitat antworten Zitat
Benutzerbild von bitsetter
bitsetter

Registriert seit: 17. Jan 2007
1.169 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Welche Auflösungen besitzt ein *.ico-File

  Alt 16. Feb 2007, 08:38
Jetzt verstehe ich auch erst, was du eigentlich erreichen möchtest.

Zitat von SittingDuck:
3. Halo-Icon unten links von Windows vergrößert Evil or Very Mad
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.
Du kannst ja mal Halo mit dem Programm Resource Hacker öffnen, und du wirst sehen, dass Halo auch 3 Icone von 48X48 in verschiedenen Farbtiefen besitzt. Auf meinem Bild kannst du sehen, dass Icon Nr. 9 also das Richtige für dich gewesen wäre.
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.
Miniaturansicht angehängter Grafiken
resha_120.jpg  
Gruß bitsetter
"Viele Wege führen nach Rom"
Wolfgang Mocker (geb. 1954), dt. Satiriker und Aphoristiker
  Mit Zitat antworten Zitat
SittingDuck

Registriert seit: 11. Jan 2006
Ort: Leverkusen
159 Beiträge
 
Delphi 2010 Professional
 
#6

Re: Welche Auflösungen besitzt ein *.ico-File

  Alt 16. Feb 2007, 11:36
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 ...
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 ...
Ciao ... SittingDuck
iPhone Backup und mehr: iTwin v3.9 Beta ... Alternative Startleiste: Launcher v3.8 !
  Mit Zitat antworten Zitat
Benutzerbild von bitsetter
bitsetter

Registriert seit: 17. Jan 2007
1.169 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: Welche Auflösungen besitzt ein *.ico-File

  Alt 17. Feb 2007, 01:32
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
Angehängte Dateien
Dateityp: zip icon48_634.zip (8,7 KB, 51x aufgerufen)
Gruß bitsetter
"Viele Wege führen nach Rom"
Wolfgang Mocker (geb. 1954), dt. Satiriker und Aphoristiker
  Mit Zitat antworten Zitat
SittingDuck

Registriert seit: 11. Jan 2006
Ort: Leverkusen
159 Beiträge
 
Delphi 2010 Professional
 
#8

Re: Welche Auflösungen besitzt ein *.ico-File

  Alt 17. Feb 2007, 09:31
Großartig so weit !!! Tolle Arbeit bitsetter. 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 ...
Ciao ... SittingDuck
iPhone Backup und mehr: iTwin v3.9 Beta ... Alternative Startleiste: Launcher v3.8 !
  Mit Zitat antworten Zitat
Benutzerbild von bitsetter
bitsetter

Registriert seit: 17. Jan 2007
1.169 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Welche Auflösungen besitzt ein *.ico-File

  Alt 17. Feb 2007, 10:23
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.
Angehängte Dateien
Dateityp: zip icon48ico_179.zip (7,7 KB, 25x aufgerufen)
Gruß bitsetter
"Viele Wege führen nach Rom"
Wolfgang Mocker (geb. 1954), dt. Satiriker und Aphoristiker
  Mit Zitat antworten Zitat
Benutzerbild von bitsetter
bitsetter

Registriert seit: 17. Jan 2007
1.169 Beiträge
 
Turbo Delphi für Win32
 
#10

Re: Welche Auflösungen besitzt ein *.ico-File

  Alt 19. Feb 2007, 00:43
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;
Gruß bitsetter
"Viele Wege führen nach Rom"
Wolfgang Mocker (geb. 1954), dt. Satiriker und Aphoristiker
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 13:09 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