Jump to bottom of this post for date/time of last update and the update.
Thought I'd share this code. The project allows you to create or modify an existing icon file. Icons & cursors can be imported from file, including animated cursors, bitmaps, jpgs, pngs, gifs, wmf/emfs, tifs and binaries like exe, dll, and ocx. Once loaded, the icons can be sorted or rearranged, individual ones can be deleted. Regarding import of bitmaps/jpgs/gifs/tifs/wmfs/emfs... Auto palettizing is in play. If image can be reduced to 8, 4 or 1 bit bitmaps, it will be done. If the source bitmap file is already paletted, no change. PNGs are not scrutinzed. Image sizes > 256 pixels in height or width will not be permitted.
Unicode is supported for file names and resource names. A lot of array manipulations and will run faster when compiled.
Many icon resources contain multiple images at varying sizes and bit depths. VB can use 99% of the icon files out there as long as a 4 or 8 bit, non-PNG icon, exists at the front of the file. So, simply by rearranging the icon order, you can use icon files that VB previously complained about not being a valid picture. Doesn't mean you can use those nice alpha-blended ones though. However, you can use them via APIs as sample code below shows.
The code is well commented and has a ton of icon handling routines that may be a good learning tool if you ever want to manage icons at such a low level.
Bonus material follows. Ever want to display a nice 32bit alphablended icon in your form's titlebar but VB won't allow it as the form's Icon property? If so, do it with APIs. Applies to XP and above.
Code:
Private Declare Function LoadImage Lib "user32.dll" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Const WM_SETICON As Long = &H80
Private Const ICON_SMALL As Long = 0
Private Const IMAGE_ICON As Long = 1
Private Const LR_DEFAULTSIZE As Long = &H40
Private Const LR_LOADFROMFILE As Long = &H10
Private Sub Command1_Click()
Dim hIcon As Long
' replace FileName below with a valid icon path/filename
hIcon = LoadImage(0&, FileName, IMAGE_ICON, 0&, 0&, LR_DEFAULTSIZE Or LR_LOADFROMFILE)
If hIcon Then
SendMessage Me.hWnd, WM_SETICON, ICON_SMALL, ByVal hIcon
End If
End Sub
Bouns #2. Well, what if you want to load that icon directly from memory without needing a file? Add the icon to a resource file and extract the bytes. You will have to use Custom resource because we need the bytes, not an icon handle.
Code:
Private Declare Function CreateIconFromResourceEx Lib "user32.dll" (presbits As Any, dwResSize As Any, ByVal fIcon As Long, ByVal dwVer As Long, ByVal cxDesired As Long, ByVal cyDesired As Long, ByVal Flags As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Const WM_SETICON As Long = &H80
Private Const ICON_SMALL As Long = 0
Private Const ICRESVER As Long = &H30000
Private Const LR_DEFAULTSIZE As Long = &H40
Private Sub Command1_Click()
Dim hIcon As Long, bData() As Byte
Dim dwOffset As Long, dwSize As Long
Dim Index As Long
' since an icon file can contain multiple icons...
Index = 0 ' set index to which icon in the custom resource you want
' 0=1st icon, and if multiple icons: 1=2nd icon, 2=3rd icon, etc
' using VarPtr vs CopyMemory. Modified 1st 2 params of API to accept params "As Any"
bData() = LoadResData(101, "Custom") ' extract icon(s) from res file
dwSize = VarPtr(bData(16& * Index + 14&)) ' get size of icon resource
dwOffset = VarPtr(bData(bData(16& * Index + 18&))) ' get offset into the array
' create the icon & assign it to your form
hIcon = CreateIconFromResourceEx(ByVal dwOffset, ByVal dwSize, 1, ICRESVER, 0&, 0&, LR_DEFAULTSIZE)
If hIcon Then
SendMessage Me.hWnd, WM_SETICON, ICON_SMALL, ByVal hIcon
End If
End Sub
TIP: The above sample code will load PNGs embedded into icon files as a valid hIcon also if run on Vista and later only.
Edited: 13 Oct 10 12:50 AM GMT/Zulu
:: Would not parse multi-sets of animated cursors contained in single cursor file (Win7). Fixed. See posts 15 & 17 below
:: Done modifying this project for enhancements. Will update due to bugs only
3 Mar 10
Bug fixes and one enhancement (as long as I found a bug)
:: Save routine did not release mapped file handle; caused some issues when saving and then adding more images afterwards, in same session. Fixed
:: BitmapToIcon routine could corrupt image data in some cases. Fixed
:: Enhancement: Imported PNGs are now loaded in both PNG & 32bpp icon format.
1 Jan 10
Included more image formats and minor corrections
:: Can now accept animated gifs and transparent gifs. GDI+ required
:: Can now accept TIFFs. GDI+ required
:: Can now accept WMF/EMFs. GDI+ required
:: Can now accept animated cursors
:: Vista/Win7 PNG-to-icon display used vs GDI+ for those operating systems
:: Binary resource extraction was ignoring PNGs again; fixed.
30 Dec 09
:: By-selection deletion was not using sorted index which led to deletion of wrong images in some cases
:: When appending images in some cases, the previously loaded images would be cleared from the cache.
:: LavaSoft's adaware.exe has some unknown/custom resources as RT_CURSORS which caused app to abort loading. Reworked the DLL/binary extraction routine to firm up recognition of properly formatted resources.
:: Added option to extract icons/cursors, icons only, cursors only from binarires.
28 Dec 09
:: Added ability to select multiple files, per request
:: Reworked project to use disk file vs memory for caching images
:: Added option to create transparent cursors along with transparent icons
24 Dec 09
:: Didn't like the way I controlled the vertical scrollbar in multiview. Better implementation now
:: For some reason, GetWindowTextLengthW could return zero when it shouldn't. Used a simpler method instead.
23 Dec 09
:: Fixed obstacle noted in reply #2 below
:: Added some additional right click functionality for the mulitview
22 Dec 09
:: In some scenarios it was possible that icons were being forced to be saved with .cur extensions
:: CreateWindowExW was being called for non-unicode O/S. Copy/paste oversight on my part - fixed
:: Oops, broke the multiview selection when I last updated. Fixed again.
21 Dec 09
:: Updated zip to fix minor logic error that can occur when reading cursors/icons from executables.
:: Hmmm, found a 256x256 32bit non-PNG icon in exe file & parser didn't like; now it does.
:: Included a secondary graphical view of the icon resources.
Last edited by LaVolpe; Nov 18th, 2017 at 09:27 AM.
Insomnia is just a byproduct of, "It can't be done"