Nasty gotcha: The inadvertently named resource

Raymond Chen

Raymond

In the resources of a Win32 module, resource files, you can identify a resource by number (ordinal) or by name (string). One horrific gotcha of the resource file format is that it doesn’t require you to quote strings that are used to name resources.

Suppose you have this resource header file.

// resource.h

#define IDD_ENTERPASSWORD 100

and you use it in your resource file like this:

#include <resource.h>

IDD_ENTERPASWORD DIALOG ...
BEGIN
    ...
END

And your code tries to use the dialog like this:

DialogBox(g_hinst, MAKEINTRESOURCE(IDD_ENTERPASSWORD),
          hwndParent, DialogProc);

Everything compiles, but the Dialog­Box function returns -1 without displaying any dialog box. Your breakpoint on the Dialog­Proc is never hit. What’s going on?

What’s going on is that in your resource file, you misspelled “password”.

IDD_ENTERPASWORD DIALOG ...

This typo was not reported by the resource compile because of the strange rule that named resources permit but do not require quotation marks around the name. If you omit the quotation marks, the resource compile will “helpfully” insert them for you. Since IDD_ENTER­PASWORD is not defined anywhere, the resource compile assumes you meant

"IDD_ENTERPASWORD" DIALOG ...

and generates a named dialog resource called "IDD_ENTERPASWORD". If you did this on purpose, then the way you would access the dialog box would be

DialogBox(g_hinst, TEXT("IDD_ENTERPASWORD"),
          hwndParent, DialogProc);

But you didn’t misspell the symbol on purpose. It was a mistake. You meant IDD_ENTER­PASSWORD. And your misspelling cost you dearly: The resource was given the wrong identifier.

Sucks to be you.

The diagnosis for this class of problems is to verify that the dialog box you describe does indeed exist.

// Diagnosing the problem: Let's see if the resource exists.
// DialogBox(g_hinst, MAKEINTRESOURCE(IDD_ENTERPASSWORD), ...)

auto res = FindResource(g_hinst,
                        MAKEINTRESOURCE(IDD_ENTERPASSWORD),
                        RT_DIALOG);

In the debugger, check the return value of Find­Resource. If it’s nullptr, then the reason the Dialog­Box function failed is that the resource didn’t exist. The next step of the investigation would be to find out why the resource isn’t there.

Maybe you misspelled it.

Raymond Chen
Raymond Chen

Follow Raymond