Some other places atoms (and the magical 0xC000) arise


The moment the Windows developers got a system for converting strings into numbers, they could use it anywhere they need to, well, convert a string into a number. Somtimes these integers are officially declared as atoms, but most of the time they are just integers that happen to be atoms under the covers.

I'll start with registered window messages, created by the RegisterWindowMessage function. These are not officially atoms; they are just integers that happen to lie in the range 0xC000 to 0xFFFF, just like atoms. But yeah, internally, they're atoms. Of course, you shouldn't rely on it since it's not contractual. Think of it as a fantastic coincidence.

Registered clipboard formats created by the RegisterClipboardFormat message are also not officially atoms; they're just UINTs. The numeric range for registered clipboard formats isn't even specified; that they hang out in the 0xC000 range is just an implementation detail. Someday, registered clipboard formats may have values like 0x1234, who knows.

Window properties are also stored in the form of atoms, but unlike the other examples above, the atomic nature of window properties is contractual. You can set a property either by passing the property name SetProp(hwnd, TEXT("PropertyName"), hData) or by passing the property atom SetProp(hwnd, MAKEINTATOM(atm), hData), where atm was obtained from an earlier call to GlobalAddAtom. There is additional weirdness with the way these atoms are tracked, which I'll defer to Friday's article, though it is hinted at in the documentation for SetProp which cautions that you need to remove all the properties from a window before it is destroyed.

Window classes also have atoms. The return value of the RegisterClass function is an ATOM, and you can also retrieve the atom later by calling GetClassWord(GCW_ATOM). We'll see more about that atom next time.

Comments (7)
  1. meh says:

    I love this stuff. I love your blog too, but that goes without saying. =]

  2. Ivo says:

    Why is RegisterClipboardFormat returning UINT and not a WORD? Even the documentation says the value is between 0xC000 and 0xFFFF. This is not a big deal in itself, but the problem is when assigning this to a CLIPFORMAT (which is defined as WORD) it requires a cast. I need to add a bunch of those recently in my project when I upped the warning level.

  3. Messiant R says:

    Going to take a guess on the additional weirdness:

    GlobalAddAtom() stuffs the atom into the atom table shared by all applications, and SetProp() seems to be using that table according to your explanation.

    If a mischievous developer decided to call GlobalDeleteAtom() more times on the window property names than he explicitly or implicitly added the atom, other applications could suddenly fail due to the disappearance of their expected atom. I guess there’s also a chance then that GlobalAddAtom() may reuse the value of the deleted atom.

    Nobody likes it if the ground sinks away under their feet, so there must be some process based reference counting going on to prevent what I described.

    Now I’ll go wait in anticipation of friday to see if my hunch is correct.

  4. Neil says:

    Think of it as a fantastic coincidence.

    Nearly fantastic; as Undocumented Windows points out, currently RegisterWindowMessage and RegisterClipboardFormat have the same address.

    Unfortunately, at least in my edition, they then explain how to load ds with the HINSTANCE of the desktop to call GetAtomName to retrieve the name of the registered message, when in fact GetClipboardFormatName already does that!

  5. IUnknown says:

    IIRC, RegisterWindowMessage calls AddAtom.

    [Thank you for repeating my second paragraph, in case people missed it the first time. -Raymond]
  6. IUnknown says:

    Heh, sorry about that. RegisterClipboardFormat is the exact same function though, it has the same prototype and even the same entry point in user32.dll. That’s all, thanks for the informative article. It’s always fun to read your blog :)

  7. knut says:

    I always wondered what RegisterWindowMessage will do when all 16 383 possible atom values are exhausted?

    With all these uses of GlobalAddAtom (Window classes,SetProp,RegisterWindowMessage,RegisterClipboardFormat,…), isn’t it very likely the string table gets ‘full’ some time?

Comments are closed.