views:

352

answers:

3

Is there a way to define and send custom message types in Win32, to be caught by your Main message handler? For example, my main message handler captures messages such as WM_PAINT, WM_RESIZE, WM_LBUTTONDOWN etc. Can I create my own WM_DOSOMETHING? If so, how would I send this message?

Ah, I actually just discovered this was asked before here, however, it doesn't answer how I would actually send this message.

+7  A: 

Yes. Just declare a constant in the WM_USER range e.g.

#define WM_RETICULATE_SPLINES (WM_USER + 0x0001)

You can also register a message by name using the RegisterWindowMessage API.

You can then send these messages using SendMessage, PostMessage or any of their variants.

itowlson
thanks! Is it necessary to RegisterWindowMessage() if the message is being sent and captured within one application only?
BeeBand
If using #define, be sure to use parentheses around (WM_USER + 0x0001) so arithmetic performed on your new message number (bitwise operations, packing into a high-order word, etc.) works correctly.
Morbo
And no, you don't need RegisterWindowMessage if there's only one application involved; only if you need two apps to agree on a single message number.
Morbo
It can be wise. WM_USER messages are private to a window class, not an application. So if your main window class defines WM_RETICULATE_SPLINES to be WM_USER + 0x0001, then send that message to a MyThirdPartyControl, the MyThirdPartyControl is at liberty to interpret that as WM_SEND_RUDE_EMAIL_TO_BOSS_THEN_FORMAT_C. So use WM_USER only for communication within a window class, or when you're sure you know which class of window you're posting to. Otherwise, RWM is safer. See the RWM docs for more info.
itowlson
Thanks Morbo, edited in parentheses.
itowlson
see http://msdn.microsoft.com/en-us/library/ms644931%28VS.85%29.aspx for a description of the message number ranges; depending on your problem, `WM_APP` might be a better fit than `WM_USER`
Christoph
Or better declare it as `const DWORD WM_RETICULATE_SPLINES = (WM_USER + 0x0001);`
Kirill V. Lyadvinsky
+5  A: 

Woah, let's just stop and think here...

First of all, Windows itself sends messages in the WM_USER+n range, that's why WM_APP was invented (I found this out the hard way). But it gets worse... there's nothing to stop badly behaved applications broadcasting WM_USER+n or WM_APP+n messages, and because human beings stole the crystal of infinite stupidity from the Gods, this does indeed happen in the real world.

So, repeat after me, the only safe message is one I define myself and can only see myself. Use RegisterWindowMessage. And even then, be untrusting. When I need a string to define a RegisterWindowMessage, I use GUIDGEN to create the string and put a human-readable app-specific prefix on the resulting gobbledygook. Because guess how many lazy programmers registered their message using "WM_MYMESSAGE" as the name... and then decided that broadcasting it would be a cool idea?

Bet on the stupidity of your fellow humans - it's always a winning bet.

If you want authoritative background on this whole topic, see here. No that's not my website, it's Joe Newcomer's.

Bob Moore
+1  A: 
  • If you created the window class, you can use the WM_USER range (or WM_APP)
  • If it is not your class, you can use WM_APP
  • If you want to broadcast the message to every top level window, register your own global message with RegisterWindowMessage
Anders