Foxite.COM Community Weblog

Foxite.COM Community Weblog - free weblog service for the Visual FoxPro Community.
Welcome to Foxite.COM Community Weblog Sign in | Join | Help
in
Home Blogs Forum Photos Forum Archives

VFP IMAGING



Extract icons from EXE, DLL and ICO files with GdiPlus-X

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 new GDIPlus-X library from VFP-X project, and require that you have at least the RELEASE 0.07. GdiPlusX is still in ALPHA version, but is already stable and reliable to do the vast majority of GDI+ tasks. 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 : Cesar Chalom
* 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 !

Published Friday, February 09, 2007 2:37 PM by cesarchalom
Filed Under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

vassilag said:

Great post Cesar, Thank you!
February 13, 2007 9:38 AM
 

EGB said:

Can 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.

Hi, I really don't know, since I don't have Office 2007. Maybe you could try and tell us if it works or not ! ???

February 13, 2007 2:15 PM
 

EGB said:

I've just tried to extract the Office 2007 icons with no luck.

That's a pity, MS probably is storing those images in a different format.

February 13, 2007 4:21 PM
 

Cesar Chalom said:

Este artículo fue traducido a espanol:

Extraer íconos de archivos EXE, DLL e ICO con Gdi+X

June 27, 2007 7:27 PM
 

Ana María Bisbé said:

Versión en Español de este artículo en / Spanish version at http://www.portalfox.com/article.php?sid=2370
July 24, 2007 7:27 PM
 

Cesar Chalom said:


This week Calvin Hsia&amp;nbsp;came with a very interesting post, Extract TreeView or ListView ImageList...
November 12, 2007 3:37 AM

What do you think?

(required) 
(optional)
(required)