Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find original name of a message obtained by RegisterWindowMessage Windows API

Tags:

c++

winapi

While debugging the application in an attempt to improve performance, I found that it loses time in processing a message that is greater then 0xC000. This is obviously a message created by the RegisterWindowMessage API. However, the application uses more than two hundreds such messages; is there a way to find the original name of the message by its numerical value?

The GetAtomName and GlobalGetAtomName fail with

ERROR_INVALID_HANDLE

error.

like image 970
Ilia Avatar asked Mar 28 '18 19:03

Ilia


1 Answers

There is no official API to get the name of a registered window message.

That being said, RegisterWindowMessage() and RegisterClipboardFormat() happen to currently share a single atom table (along with a few other API functions), so in current version of Windows, you can use GetClipboardFormatName() to get the name of a registered window message.

This is described on Raymond Chen's blog on MSDN:

How can I investigate the possibility of a lot of leaked window classes (RegisterClass)?

It so happens that in current versions of Windows, registered class names, registered clipboard format names, and registered window message names all come from the same atom table. I wish to reiterate that this is an implementation detail which can change at any time, so don't take any dependencies on this. I provide this information for diagnostic purposes, which is what we have here.

The customer can do this once they encounter the problem:

Foreach atom in (0xC000 .. 0xFFFF)
  If (GetClipboardFormatName(atom, buffer, bufferSize))
    Print buffer

This will print out the names of all the classes, clipboard formats, and registered window messages. There is room in the atom table for 16,384 atoms, and in practice there aren't more than a hundred or so, so if you see more than 15,000 entries, that's a really good sign that you're leaking classes.

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

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.

So, as I said, there is currently NO OFFICIAL API to get the name of a registered window message, but you can currently get around that by treating a registered window message the same as a registered clipboard format. But using GetClipboardFormatName() in this manner MAY break in the future if the implementation of RegisterWindowMessage() ever changes.

like image 184
Remy Lebeau Avatar answered Sep 30 '22 17:09

Remy Lebeau