Many functions and interfaces provide the option of passing either a string or an integer. The parameter is formally declared as a string, and if you want to pass an integer, you smuggle the integer inside a pointer by using the
MAKEINTRESOURCE macro. For example, the
FindResource function lets you load an resource specified by integer identifier by passing the identifier in the form
MAKEINTRESOURCE(ID). You can tell that it was the resource-loading functions who created the macro in the first place, since the name of the macro is "make integer resource."
But other functions use the
MAKEINTRESOURCE convention, too. The
GetProcAddress function lets you obtain a function exported by ordinal if you smuggle the ordinal inside a pointer:
GetProcAddress(. (You have to use
GetProcAddress explicitly takes an ANSI string.)
What if you're implementing a function whose interface requires you to accept both strings and integers-smuggled-inside strings? For example, maybe you're implementing
IContextMenu::, which needs to look at the
CMINVOKECOMMANDINFO. member and determine whether the invoker passed a string or a menu offset.
You can use the
IS_ macro. It will return non-
FALSE if the pointer you passed is really an integer smuggled inside a pointer.
MAKEINTRESOURCE work? It just stashes the integer in the bottom 16 bits of a pointer, leaving the upper bits zero. This relies on the convention that the first 64KB of address space is never mapped to valid memory, a convention that is enforced starting in Windows 7.