Of Icons and Cursors

Windows allows the storage of custom data alongside the program code, which can then be loaded at runtime by the program itself.

Windows allows the storage of more than just the program code in an application. Using resources, Windows allows the combinination of pieces of data with program code, which can then be loaded during runtime by the program itself.

This tutorial will cover two examples of this: Custom icons and custom cursors.

Icon Resources

To work with resources, two files need to be created, an .rc file and a .h file. Thankfully the Visual Studio IDE does all of the dirty work, thus I won't go into any details, which could be looked up in LaMothe's book, if necessary.

To create or load an icon, right-click on "Resource files" in the "Solution Explorer" and then select "Add Resource". Everything else should then be self-explanatory.

I found a lovely image of a barking dog and added it to my project, by the name IDI_BARKING_DOG.

Barking Dog

The resource.h looks like this:

// ICONS
#define IDI_BARKING_DOG            101

Now to load an icon into an application, the newly created resouce.h file must be included into the project and then the following two lines in the window creation process must be changed:

...

	wc.hIcon = (HICON)LoadImage(dxApp->appInstance, MAKEINTRESOURCE(IDI_BARKING_DOG), IMAGE_ICON, LR_DEFAULTSIZE, LR_DEFAULTSIZE, LR_DEFAULTCOLOR | LR_SHARED);

    wc.hIconSm = (HICON)LoadImage(dxApp->appInstance, MAKEINTRESOURCE(IDI_BARKING_DOG), IMAGE_ICON, LR_DEFAULTSIZE, LR_DEFAULTSIZE, LR_DEFAULTCOLOR | LR_SHARED);

...

The LoadImage function loads an icon, cursor, or a bitmap and returns a handle to that resource:

HANDLE WINAPI LoadImage(
  _In_opt_ HINSTANCE hinst,
  _In_     LPCTSTR   lpszName,
  _In_     UINT      uType,
  _In_     int       cxDesired,
  _In_     int       cyDesired,
  _In_     UINT      fuLoad
);

HINSTANCE hInst

As always, this is a handle to an instance, in this case, the handle to the module of the executable file that wants to contains the image to be loaded. We simply pass the handle to the instance of our application.

LPCTSTR lpszName

This long pointer to a constant string takes the location of the image to be loaded. The MAKEINTRESOURCE macro converts an integer value to a resource type compatible with the resource-management functions, and can be used in place of a string containing the name of the resource.

UINT uType

This unsigned int defines the type of the image to be loaded; it can be set to one of the following values: IMAGE_BITMAP, IMAGE_CURSOR or IMAGE_ICON.

int cxDesired and int cyDesired

Those parameters define the width and height, in pixels, of the resource to load. We simply set this to use the default size.

UINT fuLoad

This unsigned int defines further behaviour of the icon to be loaded. Check the MSDN for all possible flags, in this tutorial we used LR_DEFAULTCOLOR, which simply means that the icon is not monochromatic, and LR_SHARED, which shares the image handle if the image is loaded multiple times.


Cursor Resources

Loading a custom cursor is equally simple. To create or load a cursor, right-click on "Resource files" in the "Solution Explorer" and then select "Add Resource". Everything else should then be self-explanatory.

For example, I downloaded and loaded two StarCraft related cursor resources. The resource.h file now looks like this:

// ICONS
#define ID_ICON_BARKING_DOG            101

// CURSORS
#define ID_CURSOR_PROTOSS              102
#define ID_CURSOR_TERRAN               103

Now to load the cursor, one line must be changed in the window definition process:

...
	wc.hCursor = (HCURSOR)LoadImage(dxApp->appInstance, MAKEINTRESOURCE(ID_CURSOR_TERRAN), IMAGE_CURSOR, LR_DEFAULTSIZE, LR_DEFAULTSIZE, LR_DEFAULTCOLOR | LR_SHARED);
...


Putting It All Together

For this tutorial, only the custom icon has been added to the application. You can download the source code from here.

And that's it already. Easy.

barkingDogIcon

For more information on this topic, have a look at the third chapter of LaMothe's book.


The next tutorial will give a brief summary of the framework we created and an instruction on how to use it.


References:

  • Tricks of the Windows Game Programming Gurus, by André LaMothe
  • Microsoft Developer Network (MSDN)

<< Keyboard and Mouse A Windows-Framework for Games >>

Comments