查找通过RegisterWindowMessage Windows API获取的消息的原始名称

问题描述 投票:0回答:1

在调试应用程序以尝试提高性能时,我发现它在处理大于 0xC000 的消息时浪费了时间。这显然是由

RegisterWindowMessage
API 创建的消息。然而,该应用程序使用了超过两百个这样的消息;有没有办法通过数值找到消息的原始名称?

GetAtomName
GlobalGetAtomName
失败并显示

错误_无效_句柄

错误。

c++ winapi
1个回答
9
投票

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

话虽这么说,

RegisterWindowMessage()
RegisterClipboardFormat()
碰巧当前共享单个原子表(以及一些其他API函数),因此在当前版本的Windows中,您可以使用
GetClipboardFormatName()
来获取已注册的窗口消息的名称。

Raymond Chen 在 MSDN 上的博客对此进行了描述:

如何调查大量泄漏窗口类(RegisterClass)的可能性?

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

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

这将打印出所有类的名称、
剪贴板格式和注册的窗口消息

。原子表中有 16,384 个原子的空间,而实际上不会超过一百个左右,所以如果你看到超过 15,000 个条目,这是一个非常好的迹象,表明你正在泄漏类。

其他一些地方出现了原子(以及神奇的 0xC000)

我将从 RegisterWindowMessage 函数创建的已注册窗口消息开始。
这些不是正式的原子

;它们只是恰好位于 0xC000 到 0xFFFF 范围内的整数,就像原子一样。但是,是的,在内部,它们是原子。当然,您不应该依赖它,因为它不是合同性的。认为这是一个奇妙的巧合。 由 RegisterClipboardFormat 消息创建的注册剪贴板格式也

不是正式的原子

;它们只是 UINT。注册剪贴板格式的数字范围甚至没有指定;它们在 0xC000 范围内徘徊只是一个实现细节。有一天,注册的剪贴板格式可能会有像 0x1234 这样的值,谁知道呢。

因此,正如我所说,目前
没有官方 API

可以获取已注册窗口消息的名称,但您可以当前通过将已注册窗口消息与已注册剪贴板格式视为相同来解决此问题。但是,如果 GetClipboardFormatName() 的实现发生变化,以这种方式使用

RegisterWindowMessage()
可能会在未来中断。

© www.soinside.com 2019 - 2024. All rights reserved.