When you register a window class (with the
RegisterClass or
RegisterClassEx function),
you get an ATOM back.
What use is this atom?
You can use this atom in many places where a window class name
can be used; just convert it to a string with the
MAKEINTATOM macro.
Let’s change our
scratch program to illustrate:
ATOM g_atmClass;
BOOL
InitApp(void)
{
...
g_atmClass = RegisterClass(&wc);
if (!g_atmClass) return FALSE;
...
}
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev,
LPSTR lpCmdLine, int nShowCmd)
{
...
hwnd = CreateWindow(
MAKEINTATOM(g_atmClass), /* Class Name */
"Scratch", /* Title */
WS_OVERLAPPEDWINDOW, /* Style */
CW_USEDEFAULT, CW_USEDEFAULT, /* Position */
CW_USEDEFAULT, CW_USEDEFAULT, /* Size */
NULL, /* Parent */
NULL, /* No menu */
hinst, /* Instance */
0); /* No special parameters */
...
}
We save the atom returned by the RegisterClass
function and use it (in the form of a MAKEINTATOM)
in place of the class name.
if you run this program, you’ll see that it works exactly the same
as the old version that used the class name.
The class atom is valid as long as the class remains registered.
Functions that accept a MAKEINTATOM as the class name
include
CreateWindow,
FindWindow,
GetClassInfo,
and UnregisterClass
(and the Ex versions of them).
Why would you do this?
Well, there really isn’t much reason.
The string name works just as well as the atom,
so the atom is just one more thing to keep track of.
However, even though you don’t use it,
you have to be aware that other people might.
For example, the lpszClass member of the
CREATESTRUCT structure is usually a pointer
to a string, but it could be a MAKEINTATOM if
somebody decided to pass an atom instead of a string to
CreateWindow.
Those of you who’ve read
the first Bonus Chapter of my book
are already familiar with the program that crashed when
somebody created a window via an atom.
There is one interesting thing you can do with the atom: If you have a valid class atom, you can quickly tell whether a window belongs to that class by checking the window word for the atom:
if (GetWindowWord(hwnd, GWW_ATOM) == atom) ...
This technique saves you the trouble of calling
GetClassName and then doing a string comparison,
reducing it instead to an integer comparison.
This technique makes it very simple to
write a TestIfWndIsDialog function:
BOOL TestIfWndIsDialog(HWND hwnd)
{
return GetWindowWord(hwnd, GWW_ATOM) == (ULONG_PTR)WC_DIALOG;
}
Exercise: Discuss the limitations of the above
TestIfWndIsDialog function.
0 comments