Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Vista Icons extrahieren und als PNG speichern... (https://www.delphipraxis.net/111221-vista-icons-extrahieren-und-als-png-speichern.html)

diabox 31. Mär 2008 18:16


Vista Icons extrahieren und als PNG speichern...
 
Hallo erstmal ^^,

ich hab mich jetzt eine ganze Weile durchs Forum gewühlt und auch versucht bei Google fündig zu werden,
aber bislang ist bei mir noch nichts geglückt: Es geht um die PNG 48x48 (oder auch größer) Icons,
die Vista standardmäßig auf dem Desktop anzeigt. Ich komme mit ExtractIconEx nur an maximal 32x32...
Das Icon muss ja irgendwo in den Ressourcen der .exe sein, aber woher weiß ich welche und wie komme ich da ran...

Vielen Dank... :-)

diabox 1. Apr 2008 17:53

Re: Vista Icons extrahieren und als PNG speichern...
 
... liegt das daran, dass keiner Vista hat =D? Oder hätte ich doch besser in WinAPI gepostet?
Hab jetzt die letzten Tage weiter getestet,aber bei LoadResource mit RT_GROUP_ICON und
32bit,256x256 Icons hört es bei mir auf... Würde vllt schon reichen wenn mir jemand das
Vorgehen mit RT_GROUP_ICON bzw. das extrahieren erläutern könnte. Das als PNG speichern
kann ich eventuell allein bewältigen:
Hinweise & Teillösungen sind gerne willkommen =D

Matze 1. Apr 2008 18:33

Re: Vista Icons extrahieren und als PNG speichern...
 
Moin

Zitat:

Zitat von diabox
Würde vllt schon reichen wenn mir jemand das Vorgehen mit RT_GROUP_ICON bzw. das extrahieren erläutern könnte.

Selber groß, einfach selbst suchen: Hier im Forum suchenRT_GROUP_ICON ;)

Da findet man Themen wie dieses. Vielleicht hilft's: Vollständiges Icon extrahieren...

Grüße

diabox 1. Apr 2008 18:45

Re: Vista Icons extrahieren und als PNG speichern...
 
Erstmal danke für die Antwort - das versichert mir, dass der Beitrag sichtbar ist :mrgreen:
Habe nach "RT_GROUP_ICON" schon gesucht und eigentlich alle Beiträge bereits gelesen, davon besonders oft ^^:
"24x24, 40x40, 48x48, 60x60, ... Icons auslesen"
"Vollständiges Icon extrahieren..." //durch diesen bin ich auch erst auf LoadResource für meine Zwecke gekommen
Hatte den Code in "Vollständiges Icon extrahieren" auch schon getestet, aber gelange immer zu einer EAccessViolation.
Hier mein Code der bei Button klick ausgeführt wird...
Die icons.ico wird erstellt, aber ist 0B groß...

Delphi-Quellcode:
IconLocation:='C:\Program Files\Nero\Nero8\Nero StartSmart\NeroStartSmart.exe'; //Jetzt kennt ihr auch meine Testanwendung
SaveApplicationIconGroup('icons.ico',PChar(IconLocation));
//Edit: Ich bin davon ausgegangen, dass dies durch die großen 32bit 256x256 Icons in der EXE verursacht wurde und dass der Code bei allen bisher funktioniert hat...

diabox 2. Apr 2008 22:32

Re: Vista Icons extrahieren und als PNG speichern...
 
So habe jetzt lange, lange gesucht und getüftelt und diesen Code zu Stande bekommen.
Den wollt ich euch nicht vorenthalten... Mit der ICO zu PNG Sache habe ich noch so meine Probleme was die Transparenz anbetrifft, vielleicht fällt ja jemandem von euch dazu was ein? :-)

Hab den so gut es ging kommentiert, hoffe der ist vorzeigbar:

Unit: ExtractVistaIcon
Delphi-Quellcode:
unit ExtractVistaIcon;

interface

uses Windows, Dialogs, SysUtils;

 function ExtractIconVista(IconLocation: string; out HandleIconOut: HIcon; IconNum: Integer=0; IconNumAsIndex: Boolean=False; cxDesired: Cardinal = 0; cyDesired: Cardinal = 0; Flags: Dword = 0): Boolean;


implementation

//Diese Funktion ist in der Standard-Windows Unit nicht enthalten:
function IS_INTRESOURCE(lpszType: PChar): Boolean;
begin
  Result := ((DWORD(lpszType) shr 16) = 0);
end;

//------------------------------------------------------------------------------

var
  IconsFound: Integer;
  LastResNum: Integer;
  LastResName: string;
  //Die Callback-Funktion für EnumResourceNames
  function EnumIcon(Module: THandle; ResType: PChar; ResName: PChar; Param: Pointer): Bool; export; stdcall;
   begin
    //Die letzten Einträge überschreiben
    LastResNum:=-1;
    LastResName:='';
    //Überprüfen ob ResName eine ID (dann in LastResNum speichern) oder ein Name ist
    if IS_INTRESOURCE(ResName) then LastResNum:=Integer(ResName)
    else LastResName:=string(ResName);
     //Die Bibliothek so lange durchlaufen bis IconIndex erreicht ist
     if IconsFound = Integer(Param) then
      Result:=False
     else
      Result:=True;
     Inc(IconsFound);
   end;

//------------------------------------------------------------------------------

  function ExtractIconVista(IconLocation: string; out HandleIconOut: HIcon; IconNum: Integer=0; IconNumAsIndex: Boolean=False; cxDesired: Cardinal = 0; cyDesired: Cardinal = 0; Flags: Dword = 0): Boolean;
   var
    hLib,hRes,lRes,hResIcon,lResIcon: Cardinal;
    MRes: PAnsiChar;
    lIcon: Integer;
   begin
    Result:=False;
    //Die Bibliothek laden, welche das Icon enthält (exe oder dll)
    hLib:=LoadLibraryEx(PChar(IconLocation), 0, LOAD_LIBRARY_AS_DATAFILE);
    if hLib <> 0 then
     try
      IconsFound:=0;
     //Wenn IconNum nicht Index der Icon-Group ist, dann durchlaufe Bibliothek
     if IconNumAsIndex=False then
      //Die Bibliothek nach Icon-Groups durchsuchen und beim ersten Fund anhalten
      EnumResourceNames(hLib, RT_GROUP_ICON, @EnumIcon, IconNum)
     else
      //Wenn IconNum Index der Icon-Group ist, dann verwende IconNum als LastResNum
      LastResNum:=IconNum;
       //Ein Handle auf die gefundene Icon-Group Resource bekommen
      if LastResNum=-1 then
      hRes:=FindResource(hLib, PChar(LastResName), RT_GROUP_ICON)
      else
      hRes:=FindResource(hLib, MakeIntResource(LastResNum) , RT_GROUP_ICON);
      if hRes <> 0 then try
       //Die Resource laden
       lRes:=LoadResource(hLib, hRes);
       if lRes <> 0 then try
         if cxDesired+cyDesired<=1 then
          //Wenn die gewünschte Icongröße nicht angegeben ist, nach dem Icon suchen, das am besten für das Anzeigegerät geeignet ist
          lIcon:=LookupIconIDFromDirectory(LockResource(lRes), True)
         else
          //Andernfalls, nach dem Icon suchen, das am besten zu den Angaben passt
          lIcon:=LookupIconIDFromDirectoryEx(LockResource(lRes), True, cxDesired,cyDesired,Flags);
          //In RC-Wert konvertieren
          MRes:=MakeIntResource(lIcon);
           //Ein Handle auf die gefundene Icon Resource bekommen
          if lIcon <> 0 then begin hResIcon := FindResource(hLib, MRes, RT_ICON);
           if hResIcon <> 0 then try
            //Die Icon Resource laden
            lResIcon := LoadResource(hLib, hResIcon);
            if lResIcon <> 0 then try
              //Das Icon aus der Resource erstellen
              HandleIconOut:=CreateIconFromResourceEx(LockResource(lResIcon),
              SizeOfResource(hLib, hResIcon),
               True, $030000, cxDesired, cyDesired, Flags);
              Result:=True;
            finally
              UnLockResource(lResIcon);
            end;
           finally
            FreeResource(hResIcon);
           end;
          end;
       finally
         UnlockResource(lRes);
       end;
      finally
        FreeResource(hRes);
      end;
     finally
     FreeLibrary(hLib);
     end;
   end;
end.
Erläuterung:
Delphi-Quellcode:
function ExtractIconVista(
IconLocation: string; //Der Pfad zur Bibliothek (exe oder dll)
out HandleIconOut: HIcon; //Das Handle des Icons wird hier abgelegt
IconNum: Integer=0; //Die Nummer der Icon Gruppe in der Bibliothek: 0 = Erstes Icon; -1 = Letztes Icon
IconNumAsIndex: Boolean=False; //Wenn IconNumAsIndex = True wird IconNum als Index der Icon-Group betrachtet und die Bibliothek wird nicht nach Icon-Gruppen durchforstet
cxDesired: Cardinal = 0; //Die gewünschte Breite des Icons
cyDesired: Cardinal = 0; //Die gewünschte Höhe des Icons
Flags: Dword = 0 //Die folgenden Werte sind gültig: {
 LR_DEFAULTCOLOR = $0000;
  LR_MONOCHROME = $0001;
  LR_COLOR = $0002;
  LR_COPYRETURNORG = $0004;
  LR_COPYDELETEORG = $0008;
  LR_LOADFROMFILE = $0010;
  LR_LOADTRANSPARENT = $0020;
  LR_DEFAULTSIZE = $0040;
  LR_VGACOLOR = $0080;
  LR_LOADMAP3DCOLORS = $1000;
  LR_CREATEDIBSECTION = $2000;
  LR_COPYFROMRESOURCE = $4000;
  LR_SHARED = $8000;
}
): Boolean; //Erfolg der Funktion: True wenn das Icon erfolgreich extrahiert wurde, False wenn etwas schief gegangen ist...
Anwendungsbeispiel:
Delphi-Quellcode:
procedure TForm1.BitBtn1Click(Sender: TObject);
var
IconLocation: string;
ErgebnisIcon: TIcon;
ErgebnisIconH: hIcon;
begin
IconLocation:='C:\Program Files\Test\Test.exe';
ErgebnisIcon:=TIcon.Create;
ExtractIconVista(IconLocation,ErgebnisIconH,0,False,256,256,LR_VGACOLOR);
ErgebnisIcon.Handle:=ErgebnisIconH;
Form1.Canvas.Draw(0,0,ErgebnisIcon);
ErgebnisIcon.Free;
end;
Wie oben erwähnt: wenn jemand eine Idee zur Konvertierung ins PNG-Format hat (mit Alpha-Kanal), her damit :-)


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