|
||
|
Reading and Saving .ICO files and resources in VBThis code demonstrates how to read an icon and all the constituent image types, not just the ones the standard APIs or VB allow you to. VB allows you to load an save .ICO files through the LoadPicture and SavePicture methods, which are implemented in the StdPicture object. Unfortunately, this object was really written for 16 bit Windows and doesn't understand Win32 icons at all. A .ICO resource can contain many different images, at different colour depths. Windows uses the different sizes and colours as required in the system. There is no need to stick to the standard sizes and colour depths as shown in the image either. Icons can be defined at any size (up to a maximum of 128x128 pixels) and at any colour depth. When you load an icon using the StdPicture object, you only ever get one size: 32x32. It doesn't matter whether there isn't actually a 32x32 image in the .ICO resource, it stretches it as required (usually with horrible consequences). The loaded colour depth is also the always the default system icon colour depth. There are workarounds for the StdPicture object problem - see my tip "Create a VB Picture from an API Icon Handle" and the article "Get Icons for any File Type" for examples. However, all API methods for loading icons are restricted to only loading icon resources at the system default icon colour depth. On a system with "Show Icons Using All Available Colours" set, you can never load a 16 colour icon if a higher colour depth is available using the API methods. You can do this if you load the icon natively, though. This article briefly describes the .ICO file format and provides a class which reads icons from .ICO files and Executables and also writes to standard .ICO files. This class is also used in the Icon Explorer project. The .ICO File FormatICON files have a defined file format which is described for C programmers in an MSDN article by John Hornick. (Download this icon - there is a picture of him, or at least someone, stored in it at the 118x128 version!). A .ICO file contains the following information:
If you are interested in why there are two images in an icon, check out the Transparent Sprite Library article code, which describes the theory of using a mask and an image to implement graphics with transparent areas. In more detail, the structures to implement the above look like this:
Icons In Executable FilesIn an executable file, icons are stored in a similar structure, but there are two differences. Firstly, the structures are packed on 2 byte boundaries rather than the normal 4 bytes, and secondly the dwImageOffset member of the ICONDIRENTRY type is replaced with an integer icon ID number. Because the icons are packed on 2 bytes, you cannot write a VB structure which can be directly used to read the format, because VB automatically aligns all its structures on 4 byte boundaries. Instead you have to read all the data in bytes and then copy it into the appropriate structure. Translating it to VBTo say this wasn't particular easy to translate to VB would be understating the case a bit. I'd describe it here, but it would go on for ever! Instead, download the demonstration project and pick through that. If you'd like to know more about the DIB bitmap format used to store the images, there are two resources here:
The end result is a cFileIcon class. The interface to this class is as follows: Public Function AddImage(ByVal nWidth As Long, ByVal nHeight As Long, ByVal nColourCount As Long) As LongAdds a icon to the class with specified width,height and number of colours and returns the index of the new icon. The newly added icon is initialised to be completely black. To modify the icon, you need to add something to the class to set the DIB bits of the XOR (Image) and AND (Mask) DIBs. Public Sub CloneTo(ByRef cThis As cFileIcon)Makes a copy of one cFileIcon class to another. The cloned class (cThis) is a completely independent copy. Public Sub DrawIconImage( ByVal lHDC As Long, ByVal nIndex As Long, Optional ByVal eType As ECFIImageConstants = ecfiImage, Optional ByVal X As Long = 0, Optional ByVal Y As Long = 0, Optional ByVal lWidth As Long = 0, Optional ByVal lHeight As Long = 0, Optional ByVal eRasterOp As RasterOpConstants = vbSrcCopy )Draws either the Image or the Mask portion of the image to the specified DC, optionally at a specified X,Y position, stretching to a given width and height and drawn using one of the RasterOpConstants. Public Property Get Filename() As StringReturns the filename of the .ICO file or the Executable from which the icon was loaded. Public Property Get ImageColourCount(ByVal nIndex As Long) As LongReturns the number of colours in the icon at 1 based index nIndex. Public Property Get ImageCount() As LongReturns the number of icon resources within the currently loaded icon. Public Property Get ImageHeight(ByVal nIndex As Long) As LongReturns the height in pixels of the icon at the 1 based index nIndex. Public Property Get ImageSize(ByVal nIndex As Long) As LongReturns the number of bytes of the icon at the 1 based index nIndex. Public Property Get ImageWidth(ByVal nIndex As Long) As LongReturns the width in pixels of the icon at the 1 based index nIndex. Public Function LoadIcon(ByVal sFile As String) As BooleanLoads an icon from a .ICO file. Returns True if it succeeded, or False otherwise. An error will be raised if there is a problem loading the icon. Public Function LoadIconFromEXE( ByVal sFile As String, Optional ByVal lpID As Long = 0, Optional ByVal lpName As String = "" ) As BooleanLoads an icon from an executable file (e.g. EXE, OCX, DLL). Specify lpID if the resource has an integer ID, otherwise specify lpName. Returns True if it succeeded, or False otherwise. An error will be raised if there is a problem loading the icon. Public Function RemoveImage(ByVal nIndex As Long) As LongRemoves the icon resource ID at the 1 based index nIndex. Public Property Get ResourceID() As VariantReturns the resource ID that the current icon was extracted from, or Empty if the icon was loaded from a file. Public Function SaveIcon(Optional ByVal sFileName As String = "") As BooleanSaves the current icon resources to a .ICO file. If sFileName is not specified, the file that the icon was loaded from will be used. Returns True if successful, or False otherwise. An error will be raised if there is any problem saving the icon.
|
|
|