Windows 滥用RegisterWindowMessage会导致资源耗尽吗?

Windows 滥用RegisterWindowMessage会导致资源耗尽吗?,windows,winapi,Windows,Winapi,MSDN建议RegisterWindowMessage()函数仅用于注册要在进程之间发送的消息。如果需要在一个进程内发送消息,可以从WM_APP到0xBFFF的范围内安全地选择消息 然而,在我们的代码库中,我经常看到RegisterWindowMessage()只用于一个进程内发送的消息。我认为这样做是因为使用RegisterWindowMessage()的简单性,因为它不需要在WM_APP..0xbff范围内手动分发消息标识符 我是否正确理解,如果许多应用程序在一台机器上运行,并且它们都使用不

MSDN建议RegisterWindowMessage()函数仅用于注册要在进程之间发送的消息。如果需要在一个进程内发送消息,可以从WM_APP到0xBFFF的范围内安全地选择消息

然而,在我们的代码库中,我经常看到RegisterWindowMessage()只用于一个进程内发送的消息。我认为这样做是因为使用RegisterWindowMessage()的简单性,因为它不需要在WM_APP..0xbff范围内手动分发消息标识符


我是否正确理解,如果许多应用程序在一台机器上运行,并且它们都使用不同的字符串调用RegisterWindowMessage(),它们可能会耗尽RegisterWindowMessage()允许返回的消息标识符范围,而对于其中一些应用程序,它只会返回一个指示失败的值?在WM_APP..0xbff范围消息足够的情况下,使用RegisterWindowMessage()消息的有效原因是什么?

如果您只向自己发送消息,则没有有效的理由使用RegisterWindowMessage()


没有(记录在案的)取消注册消息的方法,因此在您的应用程序退出后,注册的消息将保留在atom表中,直到重新启动/注销(我记不清该atom表存储在何处,可能是窗口站或终端服务器会话实例)

即使在向自己发送消息时,您也需要使用RegisterWindowMessage的原因是它可以保护您免受在WM_APP+N范围内广播消息的白痴的伤害


是的,确实会发生这种情况。

一个可能的优点是Spy++可以显示更多信息性的文本,因此调试更容易一些。比较

<00058> 00330CA2 S message:0x0419 [User-defined:WM_USER+25] wParam:00000000 lParam:00000000
00330CA2 S消息:0x0419[用户定义:WM_User+25]wParam:00000000 lParam:00000000

004F0DA0 S消息:0xC2B0[已注册:“AFX\U WM\U ONCHANGE\U ACTIVE\U TAB”]wParam:00000001 lParam:02B596E8

当然,原则上可能会耗尽消息ID。另一方面,在MFC功能包的源代码中,有52个对
RegisterWindowMessage
的调用。因此,还有16300个ID可供其他应用程序使用。

滥用RegisterWindowMessage可能会使windows box无法使用。如果窗口消息名称是动态生成的,并且错误导致无法控制windows消息分配,则尤其如此。在这种情况下,windows工作站/桌面中的全局atom表将填满,任何使用User32.dll的进程(基本上是任何应用程序)都将无法启动、创建窗口等

Delphi/Borland产品中存在一个bug,它注册以ControlOfxxxxxx开头的消息,其中XXXX是内存地址(或其他动态修饰符)。频繁启动和停止的应用程序将注册多个控件,并最终耗尽原子空间。有关更多详细信息,请参阅:

C++Builder/Delphi(VCL)从
HInstance
GetModuleHandle
)和线程ID生成消息名。对于正常的可执行文件
HInstance
,线程ID的范围是有限的,VCL应用程序不太可能耗尽atom表。在VCL中内置DLL的情况下,更合理。或者当可执行文件设置了ASLR时(Windows 8认证的要求是什么)。
<00129> 004F0DA0 S message:0xC2B0 [Registered:"AFX_WM_ONCHANGE_ACTIVE_TAB"] wParam:00000001 lParam:02B596E8