查找RegisterWindowMessage Windows API

时间:2018-03-28 19:09:44

标签: c++ winapi

在调试应用程序以尝试提高性能时,我发现在处理大于0xC000的消息时会浪费时间。这显然是RegisterWindowMessage API创建的消息。但是,该应用程序使用了超过两百个这样的消息;有没有办法通过数值找到邮件的原始名称?

GetAtomNameGlobalGetAtomName失败

  

ERROR_INVALID_HANDLE

错误。

1 个答案:

答案 0 :(得分:6)

没有官方 API来获取已注册的窗口消息的名称。

话虽如此,RegisterWindowMessage()RegisterClipboardFormat()碰巧当前共享一个原子表(以及一些其他API函数),所以在当前< / em> Windows版本,您可以使用GetClipboardFormatName()获取已注册窗口消息的名称。

这是在Raymond Chen的MSDN博客上描述的:

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

  

在当前版本的Windows中,注册的类名,注册的剪贴板格式名称和注册的窗口消息名称都来自同一原子表。我想重申,这是一个实现细节,它可以随时更改,所以不要对此有任何依赖。我提供此信息用于诊断目的,这就是我们在这里所做的。

     

客户遇到问题后即可执行此操作:

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

这将打印出所有类的名称,剪贴板格式和已注册的窗口消息。原子表中有16,384个原子的空间,实际上不超过一百个,所以如果你看到超过15,000个条目,这是一个非常好的迹象,表明你正在泄漏课程。

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

  

我将从注册窗口消息开始,由RegisterWindowMessage函数创建。 这些不是正式的原子;它们只是位于0xC000到0xFFFF范围内的整数,就像原子一样。但是,内部,它们是原子。当然,你不应该依赖它,因为它不是契约性的。把它想象成一个奇妙的巧合。

     

由RegisterClipboardFormat消息创建的注册剪贴板格式也是不是正式原子;他们只是UINT。甚至没有指定注册剪贴板格式的数字范围;他们在0xC000范围内闲逛只是一个实现细节。有一天,注册的剪贴板格式可能有像0x1234这样的值,谁知道。

因此,正如我所说,目前有 NO OFFICIAL API 来获取已注册的窗口消息的名称,但您可以当前通过处理注册来解决这个问题窗口消息与注册的剪贴板格式相同。但是如果GetClipboardFormatName()的实现发生变化,将来以这种方式使用RegisterWindowMessage() MAY 就会中断。