A resource script references the icon file with a statement that looks like this:
myicon ICON iconfile.ico
where ICONFILE.ICO is the name of the icon file. This statement assigns the name ”myicon“ to the icon. In your C program, you use the LoadIcon function to obtain a handle to the icon. LoadIcon requires two parameters. The first is the instance handle of your program, generally called hInstance in WinMain. Windows needs this handle to determine which .EXE file contains the icon resource. The second parameter is the icon name from the resource script, in the form of a pointer to a null-terminated string. LoadIcon returns a value of type HICON, which is defined in WINDOWS.H.
This diagram shows the relationship between the icon name in the resource script and the LoadIcon statement in your C program:
Resource script: | myicon ICON iconfile.ico |
Program source: | hIcon = LoadIcon (hInstance, "myicon") ; |
Don't worry about uppercase and lowercase here. The resource compiler converts the name in the resource script file to uppercase and inserts the name in the resource table of the program's .EXE file header. The first time you call LoadIcon, Windows converts the string from the second parameter to uppercase and searches the resource table of the .EXE file for a matching name.
You can speed up this search by using a number (an unsigned integer) instead of a name. This number is called an ID number for the icon. Here's how it's done:
Resource script: | 125 ICON iconfile.ico |
Program source: | hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (125)) ; |
MAKEINTRESOURCE (”make an integer into a resource string“) is a macro defined in WINDOWS.H that converts a number into a far pointer. The offset address is set to the number, and the segment address is set to 0. Here's how MAKINTRESOURCE is defined in WINDOWS.H:
#define MAKEINTRESOURCE(i) (LPSTR)((DWORD)((WORD)(i)))
Windows knows that the second parameter is a number rather than a pointer to a character string because the segment address is 0.
Sample programs presented earlier in this book use predefined icons:
LoadIcon (NULL, IDI_APPLICATION) ;
Windows knows that this is a predefined icon because the hInstance parameter is set to NULL. IDI_APPLICATION happens also to be defined in WINDOWS.H in terms of MAKEINTRESOURCE:
#define IDI_APPLICATION MAKEINTRESOURCE(32512)
The predefined icons and cursors are part of the display driver file.
You can also reference the icon name using a third method that combines the string method and the number method:
Resource script: | 125 ICON iconfile.ico |
Program source: | hIcon = LoadIcon (hInstance, "#125") ; |
Windows recognizes the initial # character as prefacing a number in ASCII form.
How about a fourth method? This one uses a macro definition in a header file that is included (using the #include directive) in both the resource script and your program:
Header file: | #define myicon 125 |
Resource script: | myicon ICON iconfile.ico |
Program source: | hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (myicon)) ; |
Be careful when you use this method! Although case does not matter when the icon name is a character string, case does make a difference for identifiers that are generated from #define statements.
Using ID numbers rather than names for icons reduces the .EXE file size and speeds up the LoadIcon call. Moreover, if your program uses many icons, you'll find it easier to store the ID numbers in an array.