5

MSDN advises that RegisterWindowMessage() function is only used for registering messages to be sent between the processes. If a message is needed for sending within one process it can be safely selected from the range WM_APP through 0xBFFF.

However in our codebase I often see that RegisterWindowMessage() is used for messages only sent within one process. I suppose that this was done because of perceived simplicity of using RegisterWindowMessage() since it doesn't require manually distributing the message identifiers in the WM_APP..0xBFFF range.

Do I understand correctly that if many applications are run on one machine and they all call RegisterWindowMessage() with different strings they could exhaust the range of message identifiers allowed to return by RegisterWindowMessage() and for some of them it will just return a value indicating a failure? What could be a valid reason for using RegisterWindowMessage() messages in cases where WM_APP..0xBFFF range messages would suffice?

sharptooth
  • 167,383
  • 100
  • 513
  • 979

4 Answers4

5

IMHO there is no valid reason to use RegisterWindowMessage if you are only sending messages to yourself

There is no (documented) way to un-register a message, so after your app quits, that registered message will stay in the atom table until reboot/logoff (I can't remember exactly where this atom table is stored, the window station or terminal server session instance probably)

Anders
  • 97,548
  • 12
  • 110
  • 164
5

The reason you need to use RegisterWindowMessage even when messaging to yourself is that it protects you from the idiot who broadcasts messages in the WM_APP + N range.

Yes, this does happen.

Bob Moore
  • 6,788
  • 3
  • 29
  • 42
5

Abusing RegisterWindowMessage can potentially make a windows box unusuable. This is especially true if the window message names are dynamically generated and a bug causes out of control windows message allocation. In this case the global atom table in your windows station/ desktop will fill up and any process using User32.dll (basically, any app) will fail to start, create windows, etc.

There is a bug out there in Delphi / Borland products that registers messages that start with ControlOfsXXXXXX where XXXX is a memory address (or other dynamic modifier). Apps that are started and stopped frequently will register multiple ControlOfsXXXX atoms and eventually exhaust atom space. For more details see:

http://blogs.msdn.com/b/ntdebugging/archive/2012/01/31/identifying-global-atom-table-leaks.aspx

And

https://forums.embarcadero.com/thread.jspa?threadID=47678

harshaw
  • 113
  • 2
  • 7
  • C++Builder/Delphi (VCL) generates message name from `HInstance` (`GetModuleHandle`) and Thread ID. As for normal executable the `HInstance` does not vary and range of thread IDs is limited, it's unlikely that VCL application exhaust the atom table. More plausible is it in case of DLL built in VCL. Or when the executable has ASLR set (what is a requirement for Windows 8 certification). – Martin Prikryl Sep 30 '13 at 13:13
3

A possible advantage is that Spy++ can display more informative text, therefore debugging is a bit easier. Compare

<00058> 00330CA2 S message:0x0419 [User-defined:WM_USER+25] wParam:00000000 lParam:00000000

with

<00129> 004F0DA0 S message:0xC2B0 [Registered:"AFX_WM_ONCHANGE_ACTIVE_TAB"] wParam:00000001 lParam:02B596E8

Of course, in principle there is a chance to run out of message IDs. On the other hand, in the source code of the MFC Feature Pack there are 52 calls to RegisterWindowMessage. So there are still 16300 IDs left for other applications.

hofingerandi
  • 517
  • 4
  • 20