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
MAKEINTRESOURCEA
because
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.
How does 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.