Title: Extract Icons from .exe, .dll, .lnk (Windows Shortcut file)
Question: Extract icons contained in EXE / DLL files; the icon of a shortcut or icons contained in the target EXE
Answer:
The following code snippet could be used ,as suggested above, to extract icons contained in EXE / DLL files; the icon of a shortcut or icons contained in the target EXE the shortcut points to.
The following procedure 'ExtractFromLNK' extracts whatever icon an application/user might have chosen to associate with a shortcut. Call this function to extract shortcut icon, or the function 'ExtractIcon' to extract icons from any EXE/DLL. Both functions return the number of icons extracted and save them to the destination folder.
--------------------
function ExtractFromLNK(srcPath,destPath : String) : Integer;
var
lnk : string;
Iico : PWORD;
ico : TIcon;
hic : hicon;
begin {0}
getmem(Iico,sizeof(word));
lnk := srcPath;
Iico^ := 0;
ico := ticon.create;
hic := extractassociatedicon(Hinstance,pchar(lnk),Iico^);
try {1}
ico.h1andle := hic;
drawicon(ico.handle,0,0,hic);
if not(ico.Empty) then
ico.savetofile(destPath+changefileext(extractFileName(srcPath),'')+inttostr(iico^)+'.ico');
finally
freemem(iico,sizeof(word));
ico.free;
end; {1}
result := 1;
end; {0}
-----------------------------------------
The function 'ExtractIcon' returns the number of icons found in the expected file and saves the icons extracted in the destination folder specified
function ExtractIcon(srcPath , destPath : String) : Integer;
var
pTemp , phiconlarge , phIconSmall : ^HICON;
i, iconCount : integer;
ico : TIcon;
begin {0}
phiconlarge := nil;
phIconSmall := nil;
destPath := includetrailingbackslash(destPath);
if extractfileext(srcPath) = '.lnk' then
result := ExtractFromLNK(srcPath,destPath);
else {1}
begin
iconCount := extracticonEx(pchar(srcPath),-1,phiconlarge^,phIconSmall^,0);
result := iconCount;
if iconcount = 0 then
exit;
getmem(phiconlarge,sizeof(HICON)*iconCount);
ico := TIcon.create;
pTemp := phiconLarge;
try {2}
extracticonEx(pchar(srcPath),0,phiconlarge^,phIconSmall^,iconCount);
for i:= 0 to iconcount - 1 do
begin {3}
ico.Handle := phiconlarge^;
drawicon(ico.handle,0,0,ico.handle);
if not(ico.Empty) then
ico.savetofile(destPath+changefileext(extractFileName(srcPath),'')+inttostr(i)+'.ico');
inc(phiconlarge);
end; {3}
finally
phiconLarge := pTemp;
freemem(phiconlarge,sizeof(HICON)*iconCount);
ico.free;
end; {2}
end; {1}
end;{0}
---------------
The icons saved are large icons(usually 32 X 32), but the idea above applies equally well to small icons (16 X 16 , 12 X 12)as well - use 'phIconSmall' with a little modification.
Also saving the icons to a destination directory (which could be input using 'selectdirectory' / 'SHBrowseForFolder' API calls) is just one option, another option could be to collate all icons into a single bitmap - this is very simple (use the Imagelist component on the Win32 tab)
The code above has been reasonably tested but not comprehensively; if anyone encounters any problems please report that to me and I 'll be more than happy
to sort that out. Besides, the idea is just to demonstrate the working of the ExtracticonEx API call, the snippet is not meant to serve as a template for practise of code writing
Regards
Prashant