📄 icons.htm
字号:
<!doctype html public "-//ietf//dtd html//en">
<html>
<head>
<title>icons in win32</title>
</head>
<!--docheaderstart-->
<body bgcolor="#ffffff" link="#0000ff" topmargin="0" leftmargin="0"
background="../jpg/di1.JPG">
<!--toolbar_start-->
<!--toolbar_end-->
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="10"></td>
<td><p align="center"><font face="verdana, arial, helvetica, sans-serif" size="6"
color="#0000ff"><!--docheaderend--> <!-- this is a panda generated html file. the source is a winword document. --> <a name="msdn_icons"></a>icons in win32</font></p>
<p><font size="2"> </font><font face="verdana, arial, helvetica, sans-serif" size="2"></p>
<p>john hornick <br>
microsoft corporation</p>
<p><!--date-->created: september 29, 1995</p>
<p><!--/date--><a href="http://bailong.163.net/format/windows/ico.zip"> download the iconpro sample. </a></p>
<h2><b>abstract</b></h2>
<p>this article describes, in detail, the format and use of icons in 32-bit windows. the
following topics are covered; the format of icon resources in ico, dll and exe files, the
format of icon images in memory, windows' use of icons, windows' selection of an icon
image from an icon resource, and the apis provided to manipulate icon images. to follow
the discussion, the reader should be familiar with device independent bitmaps (dibs) and
their format. for more information about dibs, please refer to the following sources:<ul>
<li><!--bullet--> win32 sdk on-line help for the bitmapinfo structure </li>
<li><!--bullet--> knowledge base article q81498 sample: dibs and their uses</li>
<li><!--bullet--> knowledge base article q94326 sample: 16 and 32 bits-per-pel bitmap formats</li>
</ul>
<p>sample code dealing with some of the topics in this article is available in the win32
sdk sample tree in the iconpro project.</p>
<p>disclaimer internal details discussed in this article are subject to change without
notice in future versions of windows.</p>
<h2>introduction</h2>
<p>icons are a varied lot--they come in many sizes and color depths. a single icon
resource--an ico file, or an icon resource in an exe or dll file--can contain multiple
icon images, each with a different size and/or color depth. windows 95 and future versions
of windows nt (collectively referred to as "windows" from here on) extract the
appropriate size/color depth image from the resource depending on the context of the
icon's use. windows also provides a collection of apis for accessing and displaying icons
and icon images.</p>
<h2>what's in an icon?</h2>
<p>an icon resource can contain multiple icon images. for example, one icon resource--in
this case, a single .ico file--can contain images in several sizes and color depths: </p>
<h3>the ico file</h3>
<p>an icon file, which usually has the ico extension, contains one icon resource. given
that an icon resource can contain multiple images, it is no surprise that the file begins
with an icon directory:</p>
<pre><font face="courier" size="2">typedef struct
{
word idreserved; // reserved (must be 0)
word idtype; // resource type (1 for icons)
word idcount; // how many images?
icondirentry identries[1]; // an entry for each image (idcount of 'em)
} icondir, *lpicondir;
</font></pre>
<p>the <b>idcount</b> member indicates how many images are present in the icon resource.
the size of the <b>identries</b> array is determined by <b>idcount</b>. there exists one
icondirentry for each icon image in the file, providing details about its location in the
file, size and color depth. the icondirentry structure is defined as:</p>
<pre><font face="courier" size="2">typedef struct
{
byte bwidth; // width, in pixels, of the image
byte bheight; // height, in pixels, of the image
byte bcolorcount; // number of colors in image (0 if >=8bpp)
byte breserved; // reserved ( must be 0)
word wplanes; // color planes
word wbitcount; // bits per pixel
dword dwbytesinres; // how many bytes in this resource?
dword dwimageoffset; // where in the file is this image?
} icondirentry, *lpicondirentry;
</font></pre>
<p>for each icondirentry, the file contains an icon image. the <b>dwbytesinres</b> member
indicates the size of the image data. this image data can be found <b>dwimageoffset</b>
bytes from the beginning of the file, and is stored in the following format:</p>
<pre><font face="courier" size="2">typdef struct
{
bitmapinfoheader icheader; // dib header
rgbquad iccolors[1]; // color table
byte icxor[1]; // dib bits for xor mask
byte icand[1]; // dib bits for and mask
} iconimage, *lpiconimage;
</font></pre>
<p>the <b>icheader</b> member has the form of a dib bitmapinfoheader. only the following
members are used: <b>bisize</b>, <b>biwidth</b>, <b>biheight</b>, <b>biplanes</b>, <b>bibitcount</b>,
<b>bisizeimage</b>. all other members must be 0. the <b>biheight</b> member specifies the
combined height of the xor and and masks. the members of <b>icheader</b> define the
contents and sizes of the other elements of the iconimage structure in the same way that
the bitmapinfoheader structure defines a cf_dib format dib.</p>
<p>the <b>iccolors</b> member is an array of rgbquads. the number of elements in this
array is determined by examining the <b>icheader</b> member.</p>
<p>the <b>icxor</b> member contains the dib bits for the xor mask of the image. the number
of bytes in this array is determined by examining the <b>icheader</b> member. the xor mask
is the color portion of the image and is applied to the destination using the xor
operation after the application of the and mask.</p>
<p>the icand member contains the bits for the monochrome and mask. the number of bytes in
this array is determined by examining the icheader member, and assuming 1bpp. the
dimensions of this bitmap must be the same as the dimensions of the xor mask. the and mask
is applied to the destination using the and operation, to preserve or remove destination
pixels before applying the xor mask.</p>
<p><note><b>note</b> the <b>biheight</b> member of the <b>icheader</b> structure represents the
combined height of the xor and and masks. remember to divide this number by two before
using it to perform calculations for either of the xor or and masks. also remember that
the and mask is a monochrome dib, with a color depth of 1 bpp.</note></p>
<p>the following is an incomplete code fragment for reading an .ico file:</p>
<pre><font face="courier" size="2">// we need an icondir to hold the data
picondir = malloc( sizeof( icondir ) );
// read the reserved word
readfile( hfile, &(picondir->idreserved), sizeof( word ), &dwbytesread, null );
// read the type word - make sure it is 1 for icons
readfile( hfile, &(picondir->idtype), sizeof( word ), &dwbytesread, null );
// read the count - how many images in this file?
readfile( hfile, &(picondir->idcount), sizeof( word ), &dwbytesread, null );
// reallocate icondir so that identries has enough room for idcount elements
picondir = realloc( picondir, ( sizeof( word ) * 3 ) +
( sizeof( icondirentry ) * picondir->idcount ) );
// read the icondirentry elements
readfile( hfile, picondir->identries, picondir->idcount * sizeof(icondirentry),
&dwbytesread, null );
// loop through and read in each image
for(i=0;i<picondir->idcount;i++)
{
// allocate memory to hold the image
piconimage = malloc( picondir->identries[i].dwbytesinres );
// seek to the location in the file that has the image
setfilepointer( hfile, picondir->identries[i].dwimageoffset,
null, file_begin );
// read the image data
readfile( hfile, piconimage, picondir->identries[i].dwbytesinres,
&dwbytesread, null );
// here, piconimage is an iconimage structure. party on it :)
// then, free the associated memory
free( piconimage );
}
// clean up the icondir memory
free( picondir );
</font></pre>
<p>complete code can be found in the icons.c module of iconpro, in a function named <b>readiconfromicofile()</b>.</p>
<h3>dll and exe files</h3>
<p>icons can also be stored in .dll and .exe files. the structures used to store icon
images in .exe and .dll files differ only slightly from those used in .ico files.</p>
<p>analogous to the icondir data in the ico file is the rt_group_icon resource. in fact,
one rt_group_icon resource is created for each ico file bound to the exe or dll with the
resource compiler/linker. the rt_group_icon resource is simply a grpicondir structure:</p>
<pre><font face="courier" size="2">// #pragmas are used here to insure that the structure's
// packing in memory matches the packing of the exe or dll.
#pragma pack( push )
#pragma pack( 2 )
typedef struct
{
word idreserved; // reserved (must be 0)
word idtype; // resource type (1 for icons)
word idcount; // how many images?
grpicondirentry identries[1]; // the entries for each image
} grpicondir, *lpgrpicondir;
#pragma pack( pop )
</font></pre>
<p>the <b>idcount</b> member indicates how many images are present in the icon resource.
the size of the <b>identries</b> array is determined by <b>idcount</b>. there exists one
grpicondirentry for each icon image in the resource, providing details about its size and
color depth. the grpicondirentry structure is defined as:</p>
<pre><font face="courier" size="2">#pragma pack( push )
#pragma pack( 2 )
typedef struct
{
byte bwidth; // width, in pixels, of the image
byte bheight; // height, in pixels, of the image
byte bcolorcount; // number of colors in image (0 if >=8bpp)
byte breserved; // reserved
word wplanes; // color planes
word wbitcount; // bits per pixel
dword dwbytesinres; // how many bytes in this resource?
word nid; // the id
} grpicondirentry, *lpgrpicondirentry;
#pragma pack( pop )
</font></pre>
<p>the <b>dwbytesinres</b> member indicates the total size of the rt_icon resource
referenced by the <b>nid</b> member. <b>nid</b> is the rt_icon identifier that can be
passed to <b>findresource()</b>, <b>loadresource()</b> and <b>lockresource()</b> to obtain
a pointer to the iconimage structure (defined above) for this image.</p>
<p>the following is an incomplete code fragment for reading icons from a .dll or .exe
file:</p>
<pre><font face="courier" size="2">// load the dll/exe without executing its code
hlib = loadlibraryex( szfilename, null, load_library_as_datafile );
// find the group resource which lists its images
hrsrc = findresource( hlib, makeintresource( nid ), rt_group_icon );
// load and lock to get a pointer to a grpicondir
hglobal = loadresource( hlib, hrsrc );
lpgrpicondir = lockresource( hglobal );
// using an id from the group, find, load and lock the rt_icon
hrsrc = findresource( hlib, makeintresource( lpgrpicondir->identries[0].nid ),
rt_icon );
hglobal = loadresource( hlib, hrsrc );
lpiconimage = lockresource( hglobal );
// here, lpiconimage points to an iconimage structure
</font></pre>
<p>complete code can be found in the icons.c module of iconpro, in a function named <b>readiconfromexefile()</b>.</p>
<h3>in memory</h3>
<p>when dealing with icon resources in memory, the format is identical to the format used
in .exe and .dll files. apis such as <b>createiconfromresource()</b> expect to be passed
an iconimage structure. this is very convenient since <b>findresource()</b>, <b>loadresource()</b>
and <b>lockresource() </b>can be used to load the rt_icon resource in that format.</p>
<p>an hicon handle is a handle to a single icon image, or rt_icon resource. in previous
versions of windows, the size of an hicon image could be determined by calling <b>getsystemmetrics()</b>
with the sm_cyicon and sm_cxicon flags. it is now possible, however, to have hicon handles
for icons with non-standard sizes. hicon icons always have the same color format as the
display device. see the discussion of apis below for more details on how to handle icons
of different sizes and color depths using hicon handles.</p>
<h2>when in windows</h2>
<p>in windows, the system maintains the concept of two sizes of icons, small and large.
further, the shell also has a concept of small and large icons. this means that in total,
windows is aware of four different icon sizes--system small, system large, shell small,
and shell large.</p>
<p>the system small size is derived from the size of window captions. the caption size can
be adjusted from the "appearance" tab in the display properties dialog.
adjustments made to the caption size are immediately reflected in the system small icon
size. the system small size can be queried by calling <b>getsystemmetrics()</b> with the
sm_cxsmicon and sm_cysmicon parameters.</p>
<p>the system large size is defined by the video driver and therefore cannot be changed
dynamically. the system large size can be queried by calling <b>getsystemmetrics()</b>
with the sm_cxicon and sm_cyicon parameters.</p>
<p>the shell small size is defined by windows, and currently windows does not support
changing this value, nor is there currently a direct way to query this value. </p>
<p>the shell large size is stored in the registry under the following key:</p>
<pre><font face="courier" size="2">hkey_current_user\control panel\desktop\windowmetrics\shell icon size
</font></pre>
<p>the shell large size can be changed by modifying the registry or from the
"appearance" tab in the display properties dialog, which allows values from 16
to 72. following is an example of code that can be used to change the shell large icon
size by accessing the registry:</p>
<pre><font face="courier" size="2">dword setshelllargeiconsize( dword dwnewsize )
{
#define max_length 512
dword dwoldsize, dwlength = max_length, dwtype = reg_sz;
tchar szbuffer[max_length];
hkey hkey;
// get the key
regopenkey( hkey_current_user, "control panel\\desktop\\windowmetrics", &hkey);
// save the last size
regqueryvalueex( hkey, "shell icon size", null, &dwtype, szbuffer,
&dwlength );
dwoldsize = atol( szbuffer );
// we will allow only values >=16 and <=72
if( (dwnewsize>=16) || (dwnewsize<=72) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -