Tricks of the Windows Game Programming Gurus:Advanced Windows Programming

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

#### Using Icon Resources

There are only two files that you need to create to work with resources: an `.RC` file and possibly an `.H` file, if you want to make references to symbolic identifiers in the `.RC` file. I’ll cover this detail in the following pages. Of course, ultimately you need to generate an `.RES` file, but we’ll let the compiler IDE do this.

As an example of creating an `ICON` resource, let’s see how to change the icon that the application uses on the taskbar and the one next to the system menu on the window itself. If you recall, you set these icons during the creation of the Windows class with the following lines of code:

    winclass.hIcon      = LoadIcon(NULL, IDI_APPLICATION);

    winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

These lines of code load the default application icon for both the normal icon and the small version of the icon. However, you can load any icon you want into these slots by using icons that have been compiled into a resource file.

First, you need an icon to work with… I have created a cool icon to use for all the applications in this book. It’s called `T3DX.ICO` and is shown in Figure 3.3. I created the icon using VC++ 5.0’s Image Editor, which is shown in Figure 3.4. However, you can create icons, cursors, bitmaps, and so on with any program you want (as long as it supports the export type).

Figure 3.3 The `T3DX.ICO` icon bitmap.

`T3DX.ICO` is 32 pixels×32 pixels, with 16 colors. Icons can range in size from 16×16 to 64×64, with up to 256 colors. However, most icons are 32×32 with 16 colors, so let’s stick to that for now.

Once you have the icon that you’re interested in placing into a resource file, you need to create a resource file to place it in. To keep things simple, you’re going to do everything by hand. (Remember that the compiler IDE will do all this stuff for you—but then you wouldn’t learn anything, right?)

The `.RC` file contains all the resource definitions, meaning that you can have more than one resource in your program.

Figure 3.4 The VC++ 5.0 Image Editor.

> Note: Before I show you any code, I want to make a very important point about resources. Windows uses either ASCII text strings or integer IDs to refer to resources. In most cases, you can use both in your `.RC` files. However, some resources only allow you to use one or the other. In either case, the resources must be loaded in a slightly different way, and if IDs are involved, an extra `.H` file containing the symbolic cross-references must also be included in your project.

Here’s how you would define an `ICON` resource in your `.RC` script file:

Method 1—By string name:

    icon_name ICON FILENAME.ICO

Examples:

    windowicon ICON star.ico

    MyCoolIcon ICON cool.ico

or

Method 2—By integer ID:

    icon_id ICON FILENAME.ICO

Examples:

    windowicon ICON star.ico

    124 ICON ship.ico

Here’s the confusing part: Notice that there aren’t any quotes at all in method 1. This is a bit of a problem and will cause you much grief, so listen up. You might have noticed that the first example in each method of the `ICON` definitions looks exactly the same. However, one of them is interpreted as `“windowicon”` and the other as the symbol `windowicon`. What makes this happen is an additional file that you literally include in the `.RC` file (and your application’s `.CPP` file) that defines any symbolic constants. When the resource compiler parses the following line of code,

    windowicon ICON star.ico

it takes a look at any symbols that have been defined via `include` header files. If the symbol exists, the resource compiler then refers to the resource numerically by the integer ID that the symbol resolves to. Otherwise, the resource compiler assumes it’s a string and refers to the `ICON` by the string `“windowicon”`.

Thus, if you want to define symbolic `ICON`s in your `.RC` resource script, you also need an `.H` file to resolve the symbolic references. To include the `.H` file in the `.RC` script, you use the standard C/C++ `#include` keyword.

For example, suppose that you want to define three symbolic `ICON`s in your `.RC` file, which we’ll name `RESOURCES.RC`. You’ll also need an `.H` file, which we’ll name `RESOURCES.H`. Here’s what the contents of each file would look like:

Contents of `RESOURCES.H`:

    #define ID_ICON1    100 // these numbers are arbitrary

    #define ID_ICON2    101

    #define ID_ICON3    102

Contents of `RESOURCES.RC`:

    #include "RESOURCES.H"

    // here are the icon defines, note the use of C++ comments

    ID_ICON1 ICON star.ico

    ID_ICON2 ICON ball.ico

    ID_ICON3 ICON cross.ico

That’s it. Then you would add `RESOURCES.RC` to your project and make sure to `#include RESOURCES.H` in your application file, and you would be ready to rock and roll! Of course, the `.ICO` files must be in the working directory of your project so the resource compiler can find them.

Now, if you didn’t `#define` the symbols for the icons and include an `.H` file, the resource compiler would just assume that the symbols `ID_ICON1`, `ID_ICON2`, and `ID_ICON3` were literal strings. That’s how you would refer to them in the program—`“ID_ICON1”`, `“ID_ICON2”`, and `“ID_ICON3”`.

Now that I have completely upset the time/space continuum with all this stuff, let’s back up to what you were trying to do—just load a simple icon!

To load an icon by string name, do the following:

In an `.RC` file:

    your_icon_name ICON filename.ICO

In program code:

    // Notice the use of hinstance instead of NULL.

    winclass.hIcon      = LoadIcon(hinstance, "your_icon_name");

    winclass.hIconSm = LoadIcon(hinstance, "your_icon_name");

And to load by symbolic reference, you would `#include` the header containing the references to the symbols, as in the preceding example:

In an `.H` file:

    #define ID_ICON1      100 // these numbers are arbitrary

    #define ID_ICON2      101

    #define ID_ICON3      102

In an `.RC` file:

    // here are the icon defines, note the use of C++ comments

    ID_ICON1 ICON star.ico

    ID_ICON2 ICON ball.ico

    ID_ICON3 ICON cross.ico

And then the program code would look like this:

    // Notice the use of hinstance instead of NULL.

    // use the MAKEINTRESOURCE macro to reference

    // symbolic constant resource properly

    winclass.hIcon      = LoadIcon(hinstance,MAKEINTRESOURCE(ID_ICON1));

    winclass.hIconSm = LoadIcon(hinstance,MAKEINTRESOURCE(ID_ICON1));

Notice the use of the macro `MAKEINTRESOURCE()`. This macro converts the integer into a string pointer, but don’t worry about that—just use it when using `#defined` symbolic constants.

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.