Is the atom returned by RegisterClass(Ex) a "real" atom?
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_GLOBALCLASS flag, which means that collisions can occur after all.
The customer found that the call to
ERROR_CLASS_EXISTS, 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.
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.