Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
98 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Contents
 Resource Scripts
 Icons and Cursors
 Bitmaps
 Menus
 Custom Resources

 Printable version
 Discuss this article
 in the forums



The Series
 Beginning Windows
 Programming

 Using Resources
 in Win32 Programs

 Tracking Your
 Window/Using GDI

 Introduction
 to DirectX

 Palettes and Pixels
 in DirectDraw

 Bitmapped Graphics
 in DirectDraw

 Developing the
 Game Structure

 Basic Tile Engines
 Adding Characters
 Tips and Tricks

Icons and Cursors

Most of the Windows programs you use every day have their own icons built in, and now you know how it works: they're simply resources included in the EXE file. Custom cursors that are used by those programs are also included as resources. You've already seen an example of the script line that includes an icon resource, and the line for cursors is very similar. Here they are:

[identifier] CURSOR [filename] [identifier] ICON [filename]

After adding a line such as this to your script file -- make sure to include the script file in your project -- the icon or cursor specified by [filename] will be included as a resource in your EXE file. That's all there is to it! You can use any icon/cursor editor to generate the files you want to include. I use the one that's included in Visual C++.

Including the resources doesn't do a whole lot for your program, though, because you don't know how to use them yet! To get an idea for how icon and cursor resources are utilized in a program, let's revisit the window class we developed in the last article:

WNDCLASSEX sampleClass; // declare structure variable sampleClass.cbSize = sizeof(WNDCLASSEX); // always use this! sampleClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; // standard settings sampleClass.lpfnWndProc = MsgHandler; // message handler function sampleClass.cbClsExtra = 0; // extra class info, not used sampleClass.cbWndExtra = 0; // extra window info, not used sampleClass.hInstance = hinstance; // parameter passed to WinMain() sampleClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Windows logo sampleClass.hCursor = LoadCursor(NULL, IDC_ARROW); // standard cursor sampleClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // a simple black brush sampleClass.lpszMenuName = NULL; // no menu sampleClass.lpszClassName = "Sample Class" // class name sampleClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // Windows logo again

You remember this, don't you? The hIcon field specifies the icon to be used to represent the program, and the hIconSm field is the icon used on the Start Menu and the window's title bar. The hCursor field sets the cursor to be used when the mouse is within the boundaries of the window you create. I promised you we'd take a look at the functions used to fill these fields a little more closely, so here are their prototypes:

HICON LoadIcon( HINSTANCE hInstance, // handle to application instance LPCTSTR lpIconName // icon-name string or icon resource identifier ); HCURSOR LoadCursor( HINSTANCE hInstance, // handle to application instance LPCTSTR lpCursorName // name string or cursor resource identifier );

The return type is a handle to the cursor you're loading. The parameters are very straightforward:

HINSTANCE hInstance: This is a handle to the instance of your application. To load resources from your program, just pass the HINSTANCE that is passed to your WinMain() function when the program is executed. To use standard Windows resources like we did in the window class above, set this to NULL.

LPCTSTR lpIconName, lpCursorName: This is a string identifier that identifies the resource you want to load. If your script file refers to resources by string, simply pass the string. But if you're using numeric constants, the Windows header files include a macro that changes an integer to a form compatible with this parameter called MAKEINTRESOURCE().

As an example, let's look at the line that sets the icon to represent the program. Suppose your resource script file looks like this:

#include "resource.h" ICON_MAIN ICON myicon.ico CURSOR_ARROW CURSOR arrow.cur

If the identifiers ICON_MAIN and CURSOR_ARROW do not have matching #define statements somewhere in resource.h, then you would pass the corresponding string to the appropriate resource-loading function, like this:

sampleClass.hIcon = LoadIcon(hinstance, "ICON_MAIN");

Now let's say that resource.h contains a few #define directives:

#define ICON_MAIN 1000 #define CURSOR_ARROW 2000

Now you have to use the MAKEINTRESOURCE() macro to turn the numerical identifier into something of type LPCTSTR. This gives you a little more ease of flexibility in loading resources. Any of the following calls would be correct:

sampleClass.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(ICON_MAIN));
    or...
sampleClass.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(1000));
    or...
int ident = 1000;
sampleClass.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(ident));

That's about all you need to know about including icons and cursors in your programs, but I'll mention one more thing while we're on the topic. If you want to set a cursor sometime other than at the beginning of the program, there's a simple Windows function you can use to accomplish this:

HCURSOR SetCursor(HCURSOR hCursor);

The one parameter is the handle you get by calling LoadCursor(), and the handle that is returned is a handle to the previous cursor. If no previous cursor was set, the return value is NULL. Relatively painless, wouldn't you say? Let's move on to something a bit more interesting.




Next : Bitmaps