
Declaramos las funciones del api necesarias :
Private Declare Function DrawIcon Lib "user32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal hIcon As Long) As Long
'hDC- Device context of the control to be drawn to
'x, y- coordinates of where to draw the icon in the control
'hIcon-Handle of an icon
Private Declare Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As Long, ByVal lpszExeFileName As String, ByVal nIconIndex As Long) As Long
'hinst- The instance handle of the application calling ExtractIcon. Should be the name of your EXE file, or VB.EXE at runtime
'lpszExeName- Module containing icons
'iIcon%- number of the icon in the file. If you put -1 for this, it returns the amount of icons in a file
'The return value should be: 1)An icon handle 2)1 if it's not a EXE, DLL, or ICO file 3)NULL if no icons are in a file
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
'lpModuleName- The filename of a module, to get the handle of it.
Luego ponemos en el formulario un textbox llamado Text1 (para escribir el nombre del programa del que queremos sacar los iconos), un botón llamado Command1 y un picture box llamado Picture1 (para dibujar en él los iconos).
En el evento click del Command1 escribimos :
Dim NumIconos As Integer, Fichero As String, i As Integer, icono As Integer
Dim res As Integer
Fichero = Text1
Picture1.Cls
NumIconos = ExtractIcon(0, Fichero, -1)
If NumIconos > 0 Then
MsgBox "Encontré " & NumIconos & " iconos en el fichero"
For i = 0 To NumIconos - 1
MsgBox "Pulse enter para ver el icono nº " & i + 1
icono = ExtractIcon(0, Fichero, i)
Picture1.Cls
res = DrawIcon(Picture1.hdc, 0, 0, icono)
Next i
End If

Los programas pueden contener iconos grandes (32x32) y pequeños (16x16). Vamos a ver un ejemplo de cómo visualizar uno u otro :
Crearemos unn formulario con dos botones y un picture box.
En las declaraciones del formulario :
'Sample VB4/32-bit code to retrieve the regular (32x32) and
'small (16x16) icons from an .EXE file without starting the program.
'Extraction techniques using ExtractIcon only return the 32x32 icon.
'Note: If the .EXE does not include a small icon, the regular icon will be
'produced reduced to 16x16, making the function appear to have worked.
'This sample is hard-coded to look at Explorer.exe, which does have both
'icons.
'Developed by Don Bradner with the assistance of Karl Peterson when a
'particularly nasty GPF wouldn't go away. Feedback welcome to the Visual
'Basic Programmer's Journal forum on Compuserve (GO VBPJFORUM), in the
'32-bit section.
Option Explicit
Private Const MAX_PATH = 260
Private Const SHGFI_ICON = &H100
Private Const SHGFI_SYSICONINDEX = &H4000 ' get system icon index
Private Const SHGFI_LARGEICON = &H0 ' get large icon
Private Const SHGFI_SMALLICON = &H1 ' get small icon
Private Const ILD_TRANSPARENT = &H1
Private Type SHFILEINFO 'Structure used by SHGetFileInfo
hIcon As Long
iIcon As Long
dwAttributes As Long
szDisplayName As String * MAX_PATH
szTypeName As String * 80
End Type
Private Declare Function SHGetFileInfo Lib "shell32.dll" Alias "SHGetFileInfoA" (ByVal pszPath As String, ByVal dwFileAttributes As Long, psfi As SHFILEINFO, ByVal cbFileInfo As Long, ByVal uFlags As Long) As Long
Private Declare Function ImageList_Draw Lib "comctl32.dll" (ByVal himl&, ByVal i&, ByVal hDCDest&, ByVal x&, ByVal y&, ByVal flags&) As Long
Private Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long
Private shinfo As SHFILEINFO
Private WinPath As String
Private xPixels As Integer
Private yPixels As Integer
En el Load del formulario :
Dim Buffer As String
Dim nRet As Long
Buffer = Space(MAX_PATH)
nRet = GetWindowsDirectory(Buffer, Len(Buffer))
WinPath = Left(Buffer, nRet)
xPixels = Screen.TwipsPerPixelX
yPixels = Screen.TwipsPerPixelY
En el botón para ver el icono pequeño :
Dim himl As Long
Dim lpzxExeName As String '.EXE file name to get icon from
Dim nRet As Long
Dim picLeft As Long
Dim picTop As Long
lpzxExeName = WinPath & "\explorer.exe" 'Use any other executable that might contain a small icon
himl = SHGetFileInfo(lpzxExeName, 0&, shinfo, Len(shinfo), SHGFI_SYSICONINDEX Or SHGFI_SMALLICON)
'----------------------------------------------------
'set the picture box up to receive the icon, centered
'----------------------------------------------------
picLeft = (Picture1.ScaleWidth / xPixels) / 2 - 8
picTop = (Picture1.ScaleHeight / yPixels) / 2 - 8
Picture1.Picture = LoadPicture() 'Clear any existing image
Picture1.AutoRedraw = True
nRet = ImageList_Draw(himl, shinfo.iIcon, Picture1.hDC, picLeft, picTop, ILD_TRANSPARENT)
Picture1.Refresh
En el botón para ver el icono grande :
Dim himl As Long
Dim lpzxExeName As String '.EXE file name to get icon from
Dim nRet As Long
Dim picLeft As Long
Dim picTop As Long
lpzxExeName = WinPath & "\explorer.exe"
himl = SHGetFileInfo(lpzxExeName, 0&, shinfo, Len(shinfo), SHGFI_SYSICONINDEX Or SHGFI_LARGEICON)
'----------------------------------------------------
'set the picture box up to receive the icon, centered
'----------------------------------------------------
picLeft = (Picture1.ScaleWidth / xPixels) / 2 - 16
picTop = (Picture1.ScaleHeight / yPixels) / 2 - 16
Picture1.Picture = LoadPicture()
Picture1.AutoRedraw = True
nRet = ImageList_Draw(himl, shinfo.iIcon, Picture1.hDC, picLeft, picTop, ILD_TRANSPARENT)
Picture1.Refresh

