Site hosted by Angelfire.com: Build your free website today!

Home
DelphiZeus

Home

Icons to File Unit Help
A Delphi Unit with functions to Save Icons as
Files with Color Depth greater than Four Bits
Also saves Multi-Icon Files to TStream
For Delphi  4,  5, and  6
Version   1.2     July, 2004

Back to Icons To File

Why use the IconsToFile.pas? ?
To Save 256 Color and FullColor Icons to File or Stream.
The Delphi Graphics.pas unit has a TIcon, and when you use it's SaveToFile( ) method, the Icon file it produces will be in Four Bit (16 Color) Color Depth. This is fine for icons that can be used in all of the 32 bit windows systems, however the more recent Windows Operating Systems can use 256 color, Full Color and windows XP and Newer systems have the 32 Bit Full Color Icons with alpha blending. So if you save a 256 color or Full color Icon to a TIcon 16 color Icon File it will NOT look like the Full Color Icon. This IconsToFile.pas unit has three functions that can save Icons to File in five different Color Formats including 256 color, Full 24 Bit Color and Full 32 Bit Color.
These functions in this IconsToFile.pas unit are -
  • hIconToFile
  • autoIconToFile
  • IconsToStream
All of these fuctions use a hIcon (windows system Icon Handle) for the Icon Input, so you can use these functions with Delphi's TIcon.Handle or with API Icon Handles.

PLEASE NOTE -When ALL of these Icon To File functions save an Icon to a File, it will OVERWRITE an existing File WITHOUT prompting or warning.



There is a function that will convert a 32 bit alpha blend system Icon to a 24 bit Icon File without alpha blending, changing the color and mask bitbaps to more closely match how the Icon should look. This function is -

    • Icon32To24File



In Windows XP the 48x48 pixel size Icon is used in the default Explorer view, this 48x48 pixel size Icon was not used in the previous versions of windows enough to have an API function to get a 48x48 Icon Handle from an Icon File. I have included a helpful function that will get a 48x48 Icon from an Icon file. This function has nothing to do with saving an Icon to File. This function is -

    • Get48hIcon



Number of Colors in an Icon - Icon Files have Color Bitmaps that have a number of Colors they can display, determined by the Bit Count of this Bitmap. I will not attempt to explain the computer display pixel Bit Count definition and usage. I will use all of the following terms - "Color Format", "Color Depth", "Bit Count" and "Number of Colors" to refer to the Icon's Bitmap pixel definition Bit Count (which determines the number of Colors a Bitmap can use in it's pixels). If you are not familar with the Icon File's Bit Count, you should read the next section "Icons and their Color Format".


CONTENTS
TBitCount

Functions -
  hIconToFile
  autoIconToFile
  IconsToStream
  TestMultiIcons
  Icon32To24File
  Get48hIcon

Code  Samples -
autoIconToFile,    hIconToFile,    IconsToStream,    TestMultiIcons,    Icon32To24File

Icons and their Color Format
With this IconsToFile Unit, you can choose the Bit Count for the Icon file,or you can use the autoIconToFile( ) which will scan the system Icon Bitmap and automaticaly choose a Color Format for the Icon. But you should keep in mind some factors especially for Icons in the windows XP system (or newer).
Some Windows version Icon Information -
The original Windows 95 will only show icons in Four Bit (16 color) , the Second Release of win 95 can only show icons in Eight Bit (256 color) or less (no full color icons). Windows 98 and newer will show full color (24 Bit) icons. Windows XP introduces the 32 Bit full Color Icon with alpha channel Background blending. This XP 32 Bit Icon will NOT display correctly in other systems that do not use 32 bit icons. The icon Colors will be correct, but there will be Dark areas around the icon display were the Blending (shadow) effect should be, but since they do not do the blending, all you'll get is black where the edge blending and background shadows should be. Saving a 32 Bit Icon to file, without alpha chanel blending, will give you the same visual display as a 24 Bit Icon, but a larger file size.
What I am trying to say here is that only the Four Bit (16 color) icon is good in all of the windows systems. So if you save Icons to File to be used on a Windows version older than the one you are running, they may not display as they did in your system. This does not mean that you can save a full color (or 256 color) icon to 16 colors and it will look like the full color icon, it will not. To have an effective multi-system Icon File requires a "Muti-Icon" Icon file, with two four bit icons (one 16x16 and one 32x32), two eight bit Icons, two 24 bit Icons, and three 32 bit Icons (one 16x16, one 32x32, and one 48x48) with the alpha channel blending. I have included the BitC1 (two color bitmap) because you can have two color Icons, but this is no longer needed, because Black and White monitors are not used anymore.

Why a Multi-Icon File?
Whenever the Windows Operating System aquires (loads) an Icon into it's system Icon catch, it will scan the Icon file or resource in an .exe or .dll and pick the Icon that has a Color Bitmap with the same color depth (Bit Count) as the current screen (monitor) color depth (if the OS can use that Bit Count). If there is no Icon Bitmap that matches, it then searches for the closest lower bit count bitmap to create it's Icon, or use the only bitmap in a single Icon File. It will also "Create" any other size system Icons required, that are not in the Icon File or resource.


TBitCount sets the Color Format
In the hIconToFile( ) and the IconsToStream( ) functions, you will need to set the Bit Count for the file. Use the TBitCount to set the Color Depth (number of Colors, the Pixel Bit Count) in your saved Icon file.
type
  TBitCount = (BitC1, BitC4, BitC8, BitC24, BitC32);
The TBitCount Parameter should be set to the Bit Count that you want the Icon File to be saved as. There are NO guidelines I can give you for setting this parameter, since it depends on the version of windows you are using and the color information in the system's Icon Bitmap and which windows system version the Icon will be used. If BitC4 does not look right then try BitC8, and if that don't look right try BitC24, and if that don't look right, if you're in XP or newer then try the BitC32. You should not use the BitC32 unless there is alpha channel information in the Icon. If you do not know anything about the Color Format of icons then you can try the autoIconToFile( ) function.

The Number after the BitC is the Bit Count. Here is a List of the Color Formats -
  • BitC1   : One Bit, Two Color, Black and White.
  • BitC4   : Four Bit, 16 Color.
  • BitC8   : Eight Bit, 256 Color.
  • BitC24 : Twenty Four Bit, Full Color , 16 Million Colors.
  • BitC32 : Thirty Two Bit, Full Color , 16 Million Colors with Alpha Channel.
Palette Colors of Icons - The BitC1 will have a 2 color palette of black and white. The Bit4C will use a 16 color palette, with the 16 standard VGA colors. The Bit8C will use a 256 color palette with the 20 windows system colors and 236 "One Size Fits All" colors similar to the 256 color Netscape Web palette, but with a wider range.



Icons To File Functions
There are two Icon to File functions

PLEASE NOTE -When ALL of these Icon To File functions save an Icon to a File,
      it will OVERWRITE an existing file WITHOUT prompting or warning.


hIconToFile   Function - The hIconToFile( ) function will save an Icon (the Handle of a system icon in the hIcon1 parameter) as an Icon File with the Path and file Name of the FileName parameter. And you must have a TBitCount in the iconBitCount parameter, which will set the Color Format (Bit Count) of the Icon's Bitmap. Like all write to disk functions, the FileName must contain a valid Disk and path, or the function will fail. This function will fail if the hIcon1 parameter is not a valid system HICON handle. If you are using a Delphi TIcon then you can pass the TIcon.Handle as the hIcon1 parameter.

The hIconToFile function looks like this -
function hIconToFile(FileName: String; hIcon1: Cardinal; 
                     iconBitCount: TBitCount): Integer;
hIconToFile function Result - The Result of this hIconToFile function is an Integer value, if the function is successful the Result will be a positive number Above zero, with the amount of bytes written to file. A 32x32 four bit Icon File will have 766 as the Result.
If the function Fails to write an Icon to disk, then the Result will be a negative number in the list below -
ResultError
-1If the length of the FileName parameter is less than four charaters
-2The Icon Handle in the hIcon1 paramter is NOT a valid system Icon Handle
-3There was an error in the accesss of the Icons color and mask bitmaps
-4There as a system error in the retriving of an icon's bitmap pixel defintion data
-5Could not allocate enough memory to set the bitmap's information and data
-6The system could NOT create a file with the file Path and file Name in the FileName parameter, the disk may be full or not exist, or the folders in the path may not exist, or the user does not have write access to that folder or disk. Or there may be illegal path charaters in the FileName like "?" or "*"
-7A disk write error prevented the completion of writting the file to the disk, usually means the disk does NOT have the space to write all of the file

  You can see an example of code for hIconToFile in the code samples below, at this link -
  code for hIconToFile



autoIconToFile   Function - The autoIconToFile( ) function is like the hIconToFile( ) function, except there is No iconBitCount parameter. The FileName and hIcon1 parameters are like parameters in the hIconToFile function. The autoIconToFile( ) function will automaticaly try to determine a Color Format for that icon. If the icon only has black and white pixels it will be saved as a BitC1, , if the icon only uses the "standard four bit" 16 colors (VGA colors), then the icon will be saved as a BitC4. If the Icon has less than 237 colors plus the standard 20 windows colors in the windows SVGA palette, then it will be saved as a BitC8. A new pallete with All of the icon's colors is created and used for this BitC8 Icon File. . . And all Icons with more than 236 colors will be saved as a BitC24, unless there is any 32 bit Alpha Chanel information, in which case it will be saved as a BitC32. This may not be the original bit count of the Icon. This function will fail if the hIcon1 parameter is not a valid system HICON handle or the path in the Filename parameter is invalid.

The autoIconToFile function looks like this -
function autoIconToFile(FileName: String; hIcon1: Cardinal): Integer;
autoIconToFile function Result - The Result of this autoIconToFile function is an Integer value, It is exactly the same as the hIconToFile function above, see the comments and List for the Result of the hIconToFile function.

  You can see an example of code for autoIconToFile in the code samples below, at this link -
  code for autoIconToFile



IconsToStream  Function
Multi Icons to TStream

IconsToStream   Function - The IconsToStream function can save more than One Icon to a TStream, it uses the Delphi VCL TStream class as the reciever of the bytes for an Icon file. An array of TMutiIcon is used to define the icons that will be placed in the Stream. The TMutiIcon Record, used in this function, is defined as follows -
  TMutiIcon = Record
    hIcon: Cardinal;
    BitCount: TBitCount;
    end;
The TMutiIcon.hIcon is for the system Icon Handle, and the TMutiIcon.BitCount is a TBitCount that tells the function which color format to use for that hIcon. And by using an Array of TMutiIcon, it can put more than one icon in the Icon File. Many Icon files have several Icons in them, to use for the different size Icons displayed by the system (16x16, 32x32, 48x48 pixels) and the different Color Depths that your monitor can support (or the color depths that the system version can support), so there can be Four Bit, Eight Bit, 24 Bit and 32 Bit icons in the same Icon File. The system will automatically scan through a Multi-Icon file and get the first Icon in the file where the Color Format and size most closely matches it's system Icon requirements.

The Stream parameter can be a TFileStream, TMemoryStream, or other TStream decendent that can be written to. The aryMutiIcon parameter is an Array of TMutiIcon, described above. The NumIcons parameter will set the number of Icons that will be read from the Array and placed into the Stream. This number must be equal to or less than the number of elements in the array. The Maximum number of Icons allowed in one stream write is 15.

The IconsToStream function looks like this -
function IconsToStream(Stream: TStream; aryMutiIcon: Array of TMutiIcon;
                       NumIcons: Byte = 1): Integer;
IconsToStream function Result - The Result of this IconsToStream function is an Integer value, if the function is successful the Result will be a positive number Above zero, with the amount of bytes written to the stream. A 32x32 four bit Icon File will have 766 as the Result.
If the function Fails to write an Icon to stream, then the Result will be a negative number in the list below -
ResultError
-1The Stream parameter is nil or not assigned, invalid Stream
-2The NumIcons parameter is Zero, needs to be at least one
-3The NumIcons parameter is more than 15, this will only do up to 15 icons in one file.
-4The number of elements in the aryMutiIcon Array is less than the NumIcons parameter
-5The Icon Handle in one of the TMutiIcon.hIcon paramter is NOT a valid system Icon Handle
-6There was an error in the accesss of the one of the Icons color and mask bitmaps
-7There as a system error in the retriving of an icon's bitmap pixel defintion data
negative
number lower than -32
There was a write to stream error, this value is the negative number of bytes written to the stream. A few Stream write errors will cause an Exception and this function will fail, if the stream write does not write the full amount of data, then this will give a negative Result (for error).

A multi-Icon file will usually have several icons of various sizes and color depths, so the system can get an Icon of the size needed (16x16, 32x32, 48x48) and a color depth (bit count) to match the number of colors in the computer Screen's color resolution. The IconsToStream function does NOT test or examine the icons in the aryMutiIcon paramter for duplicate Size and Bit Count, but this function will fail if Any of the TMutiIcon.hIcon is not a valid system HICON handle. There is a function to test the Array of TMutiIcon for duplicate Size and Bit Count, see the TestMultiIcons function below.

  You can see an example of code for IconsToStream in the code samples below, at this link -
  code for IconsToStream




TestMultiIcons   Function - This function will test the dimentions and color depth of the Icons in the aryMutiIcon parameter, to see if there are any duplicate icon types (same dimentions, and color depth). This fuction does NOT ever write to any file, it only tests the Icons in the array. This function is meant to be used with the IconsToStream function, to check the icons before they are saved to file.

The TestMultiIcons function looks like this -
function TestMultiIcons(aryMutiIcon: Array of TMutiIcon; 
                         NumIcons: Byte): Cardinal;
The Result of the TestMultiIcons function is a Cardinal value. A function Result of Zero means that all of the icons are good and there are NO duplicates, if the Result value is above zero and below 100000 then there is at least one duplicate icon. This function will set a bit in the Cardinal Result for each duplicate Icon index. If the Result is two the second Icon (index one) is a duplicate. If the result is 4 then the third Icon (index 2) is a duplicate. If the result is 8 then the fourth Icon is a duplicate. If the result is six then the second and third Icons are duplicates. You can test the bit values of the result with a "if Result or 16 = Result then" test.
the Result values are listed below -
ResultError
less than
100000
Result Bit of the duplicate Icon is set, 2 would be the second, 16 would be the fifth, 128 would be the eighth. . . A Result Value of 20 would mean that the third and fifth icons are duplicates.
900000000The NumIcons parameter is incorrect, it MUST be One to Fifteen
900000001The number of elements in the aryMutiIcon Array is less than the NumIcons parameter
1000000000 to
1000000014
The Icon Handle in the TMutiIcon.hIcon paramter is NOT a valid system Icon Handle, the value above 1000000000 is the array Index, I.E. 1000000003 would be the array index three, the fourth array element
1000000100 to
1000000114
There was an error in the accesss of the one of the Icons color bitmaps. the value above 1000000100 is the array Index, I.E. 1000000105 would be the array index five, the sixth array elememt.
1000000200 to
1000000214
There as a system error in the retriving of an icon's bitmap data from GetObject. the value above 1000000200 is the array Index, I.E. 1000000201 would be the array index one, the second array elememt.
2000000000 to
2000000014
The Bitmap Size is NOT a standard 16x16, 32x32, or 48x48. The array index of the incorrect size icon is the value above 2000000000. , I.E. 2000000002 would be the array index two, the third array elememt.

  You can see an example of code for TestMultiIcons in the code samples below, at this link -
  code for TestMultiIcons



Icon32To24File  Function
To convert 32 bit alpha channel to 24 bit Icons

Icon32To24File   Function -
The windows XP system introduced the 32 bit Icon with alpha channel blending. When you want to have an Icon file that will be used in a windows system that does NOT support 32 bit Icons, you might use the hIconToFile function with the BitC24. If you use the hIconToFile( ) function with a 32 bit hIcon with alpha channel blending and save it as a 24 bit Icon, it will NOT look like the 32 bit Icon, because all of the alpha blending information has been lost in the conversion. With the 32 bit alpha blending Icon, the Mask bitmap is not used, the alpha channel pixel information if used as the Mask.

This Icon32To24File( ) Function will convert an alpha blend 32 bit Icon to a 24 bit Icon File. But it was designed to be used with the Microsoft Windows XP "shadowed" icons that came with that operating system. It attempts to read the alpha channel information and modifies the Mask and Color bitmaps for the 24 bit Icon, to better match the appearence of the 32 bit Icon. This will yield a 24 bit Icon that looks better than the hIconToFile( ) conversion, but will not have the edge and shadow blending of the original 32 bit Icon. There are a large number of icon alpha blending effects and options that the newer 32 bit Icon Editors can do, this function can NOT correctly translate 32 bit alpha channel blending for all of these effects and options.

The Icon32To24File function looks like this -
function Icon32To24File(FileName: String; hIcon: Cardinal): Integer;
The FileName parameter needs to be a valid file name and file path. The hIcon needs to be a valid system Icon Handle, if it is not a valid system Icon handle , the function will fail. This does NOT test the Icon to see if it has alpha channel information, and will do the conversion even if there is NO Alpha channel information. The System Icon Color Bit Count is tested, and if the system Icons are not 32 bit then this function fails.

Icon32To24File function Result - The Result of this Icon32To24File function is an Integer value, if the function is successful the Result will be a positive number Above zero, with the amount of bytes written to file. A 32x32 twenty four bit Icon File will have 3262 as the Result.
If the function Fails to write an Icon to disk, then the Result will be a negative number in the list below -
ResultError
-1If the length of the FileName parameter is less than four charaters
-2The Icon Handle in the hIcon1 paramter is NOT a valid system Icon Handle
-3There was an error in the accesss of the Icons color and mask bitmaps
-4There as a system error in the retriving of an icon's bitmap pixel defintion data
-5Could not allocate enough memory to set the bitmap's information and data
-6The system could NOT create a file with the file Path and file Name in the FileName parameter, the disk may be full or not exist, or the folders in the path may not exist, or the user does not have write access to that folder or disk. Or there may be illegal path charaters in the FileName like "?" or "*"
-7A disk write error prevented the completion of writting the file to the disk, usually means the disk does NOT have the space to write all of the file
-8The system color depth for Icons is not 32 bit, no Icon file is produced because no system Icon has any Alpha channel
-9The system could not allocate resources to produce the new 24 bit Bitmap needed for the Icon.

  You can see an example of code for Icon32To24File in the code samples below, at this link -
  code for Icon32To24File



Get48hIcon  Function
To get a system Icon Handle for a 48x48 Icon
from an Icon File, a Program file or .DLL library

Get48hIcon   Function -
There are no API functions to get a 48x48 Icon Handle, and in Windows XP the 48 pixel icon size is the default, so I have a function to get a 48 Icon handle from an Icon File. This function can get an Icon handle from a file that has an Icon in it, which includes an Icon File (.ICO), a program executable that has an Icon in it (.EXE), a library file that has an Icon in it (.DLL) and an Icon library file (.ICL). . This function will Fail if the file does NOT have an Icon bitmap in it, it does NOT get the system default explorer's Icon for a file or file type. It is intended for Icon files, but will also work with other files that have the icon bitmats in them.

The Get48hIcon function looks like this -

function Get48hIcon(FileName: String; icoIndex: Integer = 0): Integer;
The FileName parameter needs to be a valid file name and file path for an Icon file (or file with icon in it). The icoIndex is the index number of the Icon in the file, since an Icon File (.ICO) has only one icon in it, it must be Zero (the default) for all icon files. If you use a muti-Icon file, like an executable or .DLL, then you may include the index number of the icon you want to get the handle for.

Get48hIcon function Result - The Result of this Get48hIcon function is an Integer value, which will be a system Icon Handle if the function is successful. If the function Fails, the Result is Zero. You should ALWAYS test for failure (result is equal to zero) of this function.

If there is at least ONE Icon bitmap of any size in the file, this function will get a system generated 48x48 icon handle, even if the file does NOT have a 48x48 icon bitmap in it.

  You can see an example of code for Get48hIcon in the code samples below, at this link -
  code for Get48hIcon



Code Samples


Here are several Code samples to use the IconsToFile.pas unit functions. These code samples are all button clicks.

The simplest Icon to File Function is the autoIconToFile( ) function. You need to supply
a File name that the operating system can use, and a valid system Icon Handle.
If you are using a Delphi TIcon (like Application.Icon) then pass the TIcon.Handle.
You can test the result of this function for success or failure of writing the icon to disk.
A Result less than Zero indicates a failure to write to disk.
procedure TForm1.autoIconToFileClick(Sender: TObject);
begin
if autoIconToFile('E:\aTest Icon.ico', Application.Icon.Handle) < 0 then
ShowMessage('ERROR - autoIconToFile was NOT able to Write the Icon to disk file');
end;
You can also test the Result of autoIconToFile and get information about what caused
the function to fail. The Result of the autoIconToFile( ) is the same as the Result of the
hIconToFile( ), so you can look at the code below for hIconToFile( ) to see how to do this.



This Click procedure shows how to use the function, hIconToFile( ),
and here the Result of hIconToFile (as Return) is tested to display a message to correspond
to the Error code if the Return is below Zero.
procedure TForm1.Icon2FileClick(Sender: TObject);
var
ShInfo1: TSHFILEINFO;
hIcon1: Cardinal;
Return: Integer;
ReStr: String;
begin
Return := hIconToFile('E:\aTest1.ico', Application.Icon.Handle, BitC24);
if Return < 0 then
  begin
  if Return = -1 then
    ReStr := 'ERROR - File name has less than 4 charaters'
  else
  if Return = -2 then
    ReStr := 'ERROR - hIcon is NOT a valid handle for an Icon'
  else
  if Return = -3 then
    ReStr := 'ERROR - could not get Icon''s Bitmap stuctures from the operating system'
  else
  if Return = -4 then
    ReStr := 'ERROR - Icon''s Bitmap pixel definition are Invalid'
  else
  if Return = -5 then
    ReStr := 'ERROR - Could not retrive system Bitmap Data'
  else
  if Return = -6 then
    ReStr := 'ERROR - Could not Create a file with the Path and file name'
  else
  if Return = -7 then
    ReStr := 'ERROR - Could not Write to disk, disk space unavailable or disk IO error'
  else
    ReStr := 'ERROR - Undetermined Error';
  ShowMessage(ReStr);
  end else
  ShowMessage(IntToStr(Return));

{the next two hIconToFile show how to get and use system HICON with
the hIconToFile function}
SHGetFileInfo('C:\Windows\NotePad.exe', 0, ShInfo1, SizeOf(TSHFILEINFO),
             SHGFI_ICON);
ShowMessage(IntToStr(hIconToFile('E:\New1.ico', ShInfo1.hIcon, BitC24)));

if OpenPicDlg1.Execute then
  if UpperCase(ExtractFileExt(OpenPicDlg1.Filename)) = '.ICO' then
    begin
    hIcon1 := ExtractIcon(hInstance, PChar(OpenPicDlg1.Filename), 0);
    if hIcon1 > 0 then
    ShowMessage(IntToStr(hIconToFile('E:\Icon 8bit.ico', hIcon1, BitC8)));
    end;
end;




The Next button Click shows how to use the IconsToStream( ) function.
You need to supply a TStream (TFileStream, TMemoryStream) as the first parameter.
You will need to create an Array of TMutiIcon to use as the second parameter.
This will just use One TMutiIcon in the array and place this single Icon in the FileStream.

procedure TMainForm1.sbut_MultiIconClick(Sender: TObject);
var
aryMulIco: Array[0..0] of TMutiIcon;
Return: Integer;
FileStream1: TFileStream;
begin
aryMulIco[0].hIcon := Application.Icon.Handle;
AryMulIco[0].BitCount := BitC4;
FileStream1 := TFileStream.Create('E:\Multi Icon.ico', 
                                  fmCreate or fmOpenWrite or fmShareDenyWrite);
try
  Return := IconsToStream(FileStream1, aryMulIco);
  finally
  FileStream1.Free;
  end;
ShowMessage('The Result of IconsToStream is '+IntToStr(Return));
end;
You can see how to save More than One Icon in the next code -



The Next button Click shows how to use the IconsToStream( ) function with more than one Icon.
This will use a TMemoryStream as the first parameter.
This will create an Array of TMutiIcon with 4 elements to use as the second parameter.
This array will contain 4 different types of Icons, two 32x32 and two 16x16
There will be a Four Bit Icon in each size and a Eight Bit Icon in each size.

procedure TMainForm1.sbut_MultiIconClick(Sender: TObject);
var
aryMulIco: Array[0..3] of TMutiIcon;
ShInfo1: TSHFILEINFO;
Return: Integer;
MemStream1: TMemoryStream;
begin
aryMulIco[0].hIcon := Application.Icon.Handle;
aryMulIco[0].BitCount := BitC4;

SHGetFileInfo(PChar(ParamStr(0)), 0, ShInfo1, SizeOf(TSHFILEINFO),
             SHGFI_ICON or SHGFI_SMALLICON);
{the SHGetFileInfo fuction with the SHGFI_SMALLICON flag set will get
the handle of the Small Icon, 16x16}
aryMulIco[1].hIcon := ShInfo1.hIcon;
aryMulIco[1].BitCount := BitC4;

aryMulIco[2].hIcon := Application.Icon.Handle;
aryMulIco[2].BitCount := BitC8;

aryMulIco[3].hIcon := ShInfo1.hIcon;
aryMulIco[3].BitCount := BitC8;
Return := 123;
MemStream1 := TMemoryStream.Create;
try
  MemStream1.Write(Return, SizeOf(Integer));
  Return := IconsToStream(MemStream1, aryMulIco, 4);
  ShowMessage('MemStream size '+IntToStr(MemStream1.Size)+' Return '+IntToStr(Return));
  finally
  MemStream1.Free;
  end;
end;




The Next button Click shows how to use the Icon32To24File( ) function.
You should only use this function in the windows XP system or newer,
with Icons using the 32 bit Alpha Blending
This will convert the Alpha Channel blending information to the bitmaps of the Icon and save it as a 24 bit Icon.

procedure TMainForm1.sbut_Icon32to24Click(Sender: TObject);
var
ShInfo1: TSHFILEINFO;
begin
SHGetFileInfo('C:\Program Files\Internet Explorer\IExplore.exe', 0, 
               ShInfo1, SizeOf(TSHFILEINFO), SHGFI_ICON);
ShowMessage(IntToStr(Icon32To24File('E:\Icon 32 to 24.ico', ShInfo1.hIcon)));
end;




The Next button Click shows how to use the TestMultiIcons function

procedure TMainForm1.sbut_Icon2File2Click(Sender: TObject);
var
hIcon1: Cardinal;
AryMulIco: Array[0..9] of TMutiIcon;
ShInfo1: TSHFILEINFO;
Return: Cardinal;
Str1: String;
begin
hIcon1 := Application.Icon.Handle;
AryMulIco[0].hIcon := hIcon1;
AryMulIco[0].BitCount := BitC8;
AryMulIco[2].hIcon := hIcon1;
//AryMulIco[2].BitCount := BitC4;
AryMulIco[2].BitCount := BitC8;
AryMulIco[4].hIcon := hIcon1;
AryMulIco[4].BitCount := BitC1;
AryMulIco[6].hIcon := hIcon1;
AryMulIco[6].BitCount := BitC24;
//AryMulIco[6].BitCount := BitC8;
SHGetFileInfo(PChar(ParamStr(0)), 0, ShInfo1, SizeOf(TSHFILEINFO),
             SHGFI_ICON or SHGFI_SMALLICON);
AryMulIco[1].hIcon := ShInfo1.hIcon;
//AryMulIco[1].hIcon := hIcon1;
AryMulIco[1].BitCount := BitC8;
AryMulIco[3].hIcon := ShInfo1.hIcon;
//AryMulIco[3].hIcon := 22;
AryMulIco[3].BitCount := BitC4;
AryMulIco[5].hIcon := ShInfo1.hIcon;
AryMulIco[5].BitCount := BitC1;
AryMulIco[7].hIcon := ShInfo1.hIcon;
AryMulIco[7].BitCount := BitC4;
//AryMulIco[7].BitCount := BitC24;
Return := TestMultiIcons(AryMulIco, 8);
if Return > 100000 then
  begin
  if Return < 900000000 then
    Str1 := 'ERROR - Undetermined Error'
  else
  if Return = 900000000 then
    Str1 := 'ERROR - the NumIcons is zero or above 15'
  else
  if Return = 900000001 then
    Str1 := 'ERROR - the NumIcons is higher than the number of elements in the MutiIcon Array'
  else
  if Return < 1000000100 then
    Str1 := 'ERROR - the Icon index '+IntToStr(Return - 1000000000)+
                                    ', hIcon is NOT an ICON Handle'
  else
  if Return < 1000000200 then
    Str1 := 'ERROR - the Icon index '+IntToStr(Return - 1000000100)+
                                     ', is a Two Color Icon without a bits Bitmap structure'
  else
  if Return < 1000000300 then
    Str1 := 'ERROR - the Icon index '+IntToStr(Return - 1000000200)+
                     ', the hIcon Bitmap will not get system Object information from GetObject( )'
  else
  if Return <  2000000100 then
  Str1 := 'ERROR - the Width and Height of Icon is Incorrect for a standard Icon, for icon index '+
              IntToStr(Return - 2000000000)
  else
  Str1 :='ERROR - Undetermined Error';
  end else // Return > 100000
if Return <> 0 then
begin
{you can use the test for a bit in the Result with a
if Return and 2 <> 0 then
The first bit will never be set, since there are no Icons before it}
Str1 := 'Duplicate Icon Indexes are ';
if Return and 2 <> 0 then
Str1 := Str1+'1, ';
if Return or 4 = Return then
Str1 := Str1+'2, ';
if Return or 8 = Return then
Str1 := Str1+'3, ';
if Return or 16 = Return then
Str1 := Str1+'4, ';
if Return or 32 = Return then
Str1 := Str1+'5, ';
if Return or 64 = Return then
Str1 := Str1+'6, ';
if Return or 128 = Return then
Str1 := Str1+'7, ';
if Return or 256 = Return then
Str1 := Str1+'8, ';
if Return or 512 = Return then
Str1 := Str1+'9, ';
if Return or 1024 = Return then
Str1 := Str1+'10, ';
if Return or 2048 = Return then
Str1 := Str1+'11, ';
if Return or 4096 = Return then
Str1 := Str1+'12, ';
if Return or 8192 = Return then
Str1 := Str1+'13, ';
if Return or 16384 = Return then
Str1 := Str1+'14, ';
if Return or 32768 = Return then
Str1 := Str1+'15';
end else
Str1 := 'All Icons are GOOD';
ShowMessage(Str1+' | '+IntToStr(Return));
end;




The Next button Click shows how to use the Get48hIcon( ) function.
In windows XP the 48x48 Icon is used as the default in the explorer folder list view.
To get a Handle for a 48 size icon, use the file name in this function

procedure TMainForm1.sbut_Get48hIconClick(Sender: TObject);
var
Filename: String;
hIcon48: Integer;
begin
FileName := 'C:\Icons\My Icon.ico';
hIcon48 := Get48hIcon(FileName);
if hIcon48 <> 0 then
    DrawIconEx(Canvas.Handle,60,48, hIcon48, 0, 0, 0, 0, DI_NORMAL) else
      ShowMessage('FAILURE - Get48hIcon');
DestroyIcon(hIcon48);
end;
To get a 48 Icon from a program file or library, you can include the Icon Index number
procedure TMainForm1.sbut_Get48hIconClick(Sender: TObject);
var
Filename: String;
hIcon48: Integer;
begin
FileName := 'C:\Windows\Notepad.exe';
hIcon48 := Get48hIcon(FileName, 1);
if hIcon48 <> 0 then
    DrawIconEx(Canvas.Handle,60,48, hIcon48, 0, 0, 0, 0, DI_NORMAL) else
      ShowMessage('FAILURE - Get48hIcon');
DestroyIcon(hIcon48);
end;


Back to Icons To File
       

Lesson -     One  Two  Three  Four  Five  Six  Seven  Eight  Nine  Ten




H O M E