Some types of files allow to store various icons together with other binary data, such as exes and dlls. .ICO files also allow to store more than one icon in a single file. Windows uses this a lot, and stores almost all the icons that it uses all the time in some dll or exe libraries.
The GdiplusX library can easily extract these icons, using the function “ExtractAssociatedIcon” from the xfcIcon class, as follows:
important:
All samples below use the Gdiplus-X library from VFP-X project. Download the latest stable release from codeplex:
http://www.codeplex.com/wiki/view.aspx?projectname=vfpx&title=gdiplusx
* the following code example demonstrates how to extract icons from an exe file
do locfile("system.app")
local lcfile, lnindex
local loicon as xfcicon
local lobmp as xfcbitmap
lcfile = getfile("exe;ico;dll") && _vfp.servername
lnindex = 0
with _screen.system.drawing
do while .t.
loicon = .icon.extractassociatedicon(lcfile, lnindex)
if isnull(loicon)
exit
endif
lcNewfile = "c:\" + justfname(lcfile) + transform(lnindex) + ".png"
lobmp = loicon.tobitmap()
lobmp.save(lcnewfile, .imaging.imageformat.png)
lnindex = lnindex + 1
enddo
endwith
return
The file extracticons.scx in the samples folder brings a form that permits you to select any file, and GdiplusX will draw all associated icons inside an imagecanvas object, like in the picture below:
need more icons ?
In my tests, after I created this function, I was very curious about what icons my computer could be storing inside so many executables and dlls installed, so I created a simple program that will scan through a selected directory, and does a recursive search in all of its subfolders, looking for all the files that can possibly store icons.
To my surprise, lots, really thousands of icons emerged... and very interesting results, I ensure you !
You can try this in your computer too.
Save the program below as howto_extracticonsfromdir2.prg in the help folder of the library. It uses a very cool routine from michael reynolds, that he kindly published in www.fox.wikis.com to obtain the names of all files from the subdirectories. Please note that this will consume some big efforts from your machine, so be prepared to wait about a minute till this task is finished. after running this sample, all the icons will be stored in “c:\myicons\”.
* file : howto_extracticonsfromdir2.prg
* author : VFPIMAGING
* save this file in the help directory in the gdiplus-x library folder
*
* the following code performs the following actions:
*
* asks the user for a path
* creates a cursor containing all available file names (exe, dll and ico)
* from the selected and its subfolders
* scans the cursor and extract all associated icons from each file
* init gdi+
do locfile("system.app")
* create destination directory to receive the extracted icons
lcdir = "c:\myicons\"
if not directory(lcdir)
mkdir (lcdir)
endif
* create the cursor that will store the valid file locations
create cursor recursive (cfile c(250))
local lccurdrive, lccurdir, lcselecteddir
lccurdrive = justdrive(fullpath(curdir()))
lccurdir = curdir()
lcselecteddir = getdir()
if empty(lcselecteddir)
wait window "invalid directory"
return .f.
endif
wait window "retrieving folders information" nowait
* scan through the selected and the subfolders
=recurse(getdir())
chdir &lccurdrive.&lccurdir.
* browse
with _screen.system.drawing
local lcfile, lnindex, lntotrec
local lnoldpercentage, lnpercentage
local loicon as xfcicon
local lobmp as xfcbitmap
store 0 to lnpercentage, lnoldpercentage
lntotrec = reccount()
scan
lcfile = recursive.cfile
lnindex = 0
do while .t.
loicon = null
* extract the associated icon
loicon = .icon.extractassociatedicon(lcfile, lnindex)
if isnull(loicon)
exit
endif
lcnewfile = lcdir + justfname(lcfile) + transform(lnindex) + ".png"
lobmp = null
* send the icon to a gdi+ bitmap object
lobmp = loicon.tobitmap()
if vartype(lobmp) <> "o"
exit
endif
* save the bitmap as png
lobmp.save(lcnewfile, .imaging.imageformat.png)
lnindex = lnindex + 1
enddo
* show progression
lnrec = recno()
lnpercentage = round((lnrec / lntotrec),1)
if lnpercentage > lnoldpercentage
wait window "extracting icons from files..." + chr(13) + ;
"elapsed: " + transform(lnpercentage * 100) + " %" nowait
lnoldpercentage = lnpercentage
endif
endscan
endwith
return
*****************************************************************************************
* function : recurse
* author : michael reynolds
* description : good for performing file processing throughout an entire directory tree.
* the function, recurse(), is called with the full path of a directory.
* recurse() will then read all files and directories in the path.
* a function can be called to process files that it finds.
* plus, the function calls itself to process any sub-directories.
* http://fox.wikis.com/wc.dll?wiki~recursivedirectoryprocessing~vfp
*****************************************************************************************
function recurse(pcdir)
local lnptr, lnfilecount, lafilelist, lcdir, lcfile
chdir (pcdir)
dimension lafilelist[1]
*--- read the chosen directory.
lnfilecount = adir(lafilelist, '*.*', 'd')
for lnptr = 1 to lnfilecount
if 'd' $ lafilelist[lnptr, 5]
*--- get directory name.
lcdir = lafilelist[lnptr, 1]
*--- ignore current and parent directory pointers.
if lcdir != '.' and lcdir != '..'
*--- call this routine again.
recurse(lcdir)
endif
else
*--- get the file name.
lcfile = lower(fullpath(lafilelist[lnptr, 1]))
*--- insert into cursor if .exe, .ico or .dll
if inlist(lower(justext(lcfile)),"dll","exe","ico")
insert into recursive (cfile) values (lcfile)
endif
endif
endfor
*--- move back to parent directory.
chdir ..
endfunc
important:
The above procedure shows how to extract the associated icons from some files. Before using those icons in your applications, you first need to make sure you have the rights to do that. Read carefully the eula from those applications prior to using them !
I hope you enjoy !
Great post Cesar, Thank you!
ReplyDeleteCan I extract the office 2007 icons with this class? I'm just wondering since many icon extractor tools out there do not extract these icons, it looks like they use a different file format or are stored differently.
ReplyDeleteHi, I really don't know, since I don't have Office 2007. Maybe you could try and tell us if it works or not ! ???
I've just tried to extract the Office 2007 icons with no luck.
ReplyDeleteThat's a pity, MS probably is storing those images in a different format.
Versión en Español de este artículo en / Spanish version at http://www.portalfox.com/article.php?sid=2370
ReplyDeletei was trying to run your example but it didn't work for me. the exAmple that brings all icons into the folder myicons it run and looks like its work but there are nothing in the directory at end.
ReplyDeletei really want to know how it work this exaple.
can you help me please?
Please check the captions of the API declarations. Unfortunately, when this blog was migrated to "WordPress", all the capitalizations were lost.
ReplyDelete"O" not "o"
ReplyDelete"D" not "d"