Sub ShowIcon(ByVal hMod As Long, sIcon As String)
BugAssert (hMod <> hNull) And (sIcon <> sEmpty)
‘ Load icon resource
hResourceCur = LoadImage(hMod, sIcon, IMAGE_ICON, 0, 0, 0)
With pbResource
If hResourceCur <> hNull Then
‘ Convert icon handle to Picture
Dim pic As New StdPicture
Set pic = IconToPicture(hResourceCur)
pbResource.PaintPicture pic, 0, 0
ordResourceLast = RT_ICON
Else
pbResource.Print “Can’t display icon: “ & sCrLf & sCrLf & _
WordWrap(ApiError(Err.LastDllError), 25)
End If
End With
End Sub
Icon groups usually contain several different icons of different sizes and possibly different resolutions. The system is supposed to go through the list of images and pick the image that best matches the current display adapter and context. The StdPicture class doesn’t know anything about multiple images in the same icon file, so I’ll have to use raw GDI functions to process multiple icons. Worse, there’s no good API function to iterate through the images in an icon resource. You have to do it the hard way by reading semi-random bytes from semi-random offsets in the resource memory.
You can use icons to create animation. The technique works much like the CPictureGlass class described in Chapter 7 except that Windows does all the dirty work. Just create an icon of the desired size and draw it wherever you want. The problem is that you’ll seldom want to do animation based on the standard icon sizes, but it’s difficult to get icons of arbitrary size. Many icon tools know how to create only standard sizes. The icon editor in Visual C++ 5.0 can create an icon of arbitrary size, but you must make sure that your 56 by 45 pixel icon image is the only one in the resulting icon file. The icon editor will try to give you a second icon image of standard size, but you should delete it. You can’t load your arbitrary-sized icon into a Picture with Visual Basic’s LoadPicture or with my IconToPicture, but you can load it and get an icon handle with LoadImage. Once you’ve got the handle, you can draw the transparent image with DrawIconEx.
Sub ShowIcons(ByVal hMod As Long, sIcon As String)
‘ Find the resource
§
‘ Allocate memory block, get size, get pointer, and allocate array
§
‘ Get image count and set up first entry
§
For i = 0 To cImage - 1
‘ Get size and colors of current icon in write to string s
§
‘ Find, load, size, allocate, and copy entry
§
‘ Real code begins here
‘ Create an icon from resource data
hIcon = CreateIconFromResource(abEntry(0), cRes, True, &H30000)
‘ Draw icon and print description
Call DrawIconEx(pbResource.hDC, 0, pbResource.CurrentY, hIcon, _
dxIcon, dyIcon, 0, hNull, DI_NORMAL)
pbResource.Print s
‘ Move to next entry
pbResource.CurrentY = pbResource.CurrentY + dyIcon
pbResource.CurrentX = 75
iImage = iImage + cEntrySize
Next
pbResource.ScaleMode = vbTwips
hResourceCur = hIcon
ordResourceLast = RT_ICON
End Sub
All that fancy code to extract resources from executable files is wasted on icons. Windows provides the ExtractIcon and ExtractIconEx API functions to do it all for you (although it lacks corresponding ExtractBitmap and ExtractCursor functions). If you simply need icons, do it the easy way. The following code loops through all the icons in a program:
ExtractIcon
c = ExtractIcon(App.hInstance, sExe, -1)
For i = 0 To c - 1
hIcon = ExtractIcon(App.hInstance, sExe, i)
‘ Do something with icon here
Loop