A customer was debugging some code that calls
RegisterClass
on a class that's already been
registered.
In this case, it was registered by another DLL in the same process.
Normally, this wouldn't be a problem,
because
each DLL passes its own instance handle to
RegisterClass
so that there are no name collisions.
However, in this case, both DLLs are passing the
CS_
flag,
which means that collisions can occur after all.
The customer found that the call to
ERROR_
,
which makes sense in the case of a collision in the global class table.
The code then calls
FindAtom
to look up the class name,
but FindAtom
fails, saying,
"No such atom."
Does this mean that the class atom created by RegisterClass
isn't a real atom?
How can you get the atom for a window class that somebody else has
registered?
Okay, let's look at these questions in order.
Is the atom a real atom? Well, if you ask the atom, it'll say, "I feel real to me." But remember that there are many atom tables in the system.
- The global atom table.
- One local atom table for each process.
- The registered clipboard format atom table.
- The registered window class atom table.
- Possibly others, too.
The FindAtom
function searches the process's
local atom table,
so if you go looking for a registered window class atom there,
you're going to come up empty.
There is no way to query the registered window class atom table
directly.
You only get indirect access to create items in it through
RegisterClass
,
and that atom can in turned by used
as a synonym for the class name.
Now, it so happens that although the
GetClassInfo
function formally returns
a BOOL
, i.e., an integer that is zero on failure
or nonzero on success,
the success case of GetClassInfo
actually returns the class atom.
This behavior is not documented,
but the ATL library relies on it,
so if the undocumented behavior changes in the future,
it'll have an app compat shim to keep ATL happy.