Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define private base Application messages?

I'm was using private messages in my application for year like this:

UM_APP_BASE = WM_APP; // WM_APP is declared as WM_APP = $8000; in "Controls" unit.

and then defined my private messages:

UM_EXPLORER_MSG = UM_APP_BASE + 1;
UM_LICENSE_CHANGE_MSG = UM_APP_BASE + 2;
etc...

And use them like this in my class:

procedure UMLicenseChanged(var Message: TMessage); message UM_LICENSE_CHANGE_MSG;

(I also use RegisterWindowMessage to "talk" to my other applications but that is a different story)

I don't remember what made me decide to use WM_APP rather than WM_USER as base in the first place.
The docs says:

The WM_USER constant is used to distinguish between message values that are reserved for use by Windows and values that can be used by an application to send messages within a private window class. There are five ranges of message numbers:

Range   Meaning
0 through WM_USER - 1   Messages reserved for use by Windows.
WM_USER through 0x7FFF  Integer messages for use by private window classes.
0x8000 through 0xBFFF   Messages reserved for future use by Windows.
0xC000 through 0xFFFF   String messages for use by applications.
Greater than 0xFFFF Reserved by Windows for future use.

Which means that WM_APP is "reserved for future use by Windows". On the other hand Delphi uses CM_BASE = $B000; which is in that range. and also CN_BASE = $BC00;

How do I define the base message so it wont collide with other messages used both by Windows/Delphi/Other controls? Which base message is preferred as private for my application? and why?
Should I use WM_USER instead of WM_APP? Note that WM_USER base is used in CommCtrl by Windows also e.g. TB_ENABLEBUTTON = WM_USER + 1. etc...

I need some insights on this issue.


I read this on my Delphi help API (D5). which is obviously obsolete!
This is probably why I have decided to use WM_APP.
Still, an explanation about the difference between the two would be nice :)

like image 204
kobik Avatar asked Dec 15 '13 15:12

kobik


1 Answers

I'm not sure where your information comes from. The MSDN documentation says:

0 through WM_USER –1
Messages reserved for use by the system.

WM_USER through 0x7FFF
Integer messages for use by private window classes.

WM_APP (0x8000) through 0xBFFF
Messages available for use by applications.

0xC000 through 0xFFFF
String messages for use by applications.

Greater than 0xFFFF
Reserved by the system.


Now, what is the difference between the WM_USER range, and the WM_APP range? This has been covered in many places. For instance, here is what Raymond Chen has to say.

0x400 .. 0x7FFF (WM_USER .. WM_APP-1): Class-defined messages.

The meanings of these messages is determined by the implementor of the window class. (Informally: By the person who calls RegisterClass for that window class.) For example, the WM_USER+1 message means TB_ENABLEBUTTON if the window is a toolbar control, but it means TTM_ACTIVATE if it is a tooltip control, and it means DM_SETDEFID if it is a dialog box. If you created your own control, it would mean something else completely different. Since anybody can create a message in this range, the operating system does not know what the parameters mean and cannot perform automatic marshalling.

0x8000 .. 0xBFFF (WM_APP ... MAXINTATOM-1): Application-defined messages.

The meanings of these messages is determined by the application that created the window. (Informally: By the person who calls CreateWindow.) This message region was created in Windows 95 to ensure that applications which subclass a window and generate custom messages will not interfere with new messages created by the window class in future versions. Again, since anybody can create a message in this range, the operating system does not know what the parameters mean and cannot perform automatic marshalling.

The main thing to take from all this is that if you define messages in the WM_USER range, then be prepared for other controls in your application to have their own use for those same messages. For instance, you must not broadcast messages in the WM_USER range.

On the other hand, messages in the WM_APP range are intended to have the same meaning for all different window classes in an application.

like image 146
David Heffernan Avatar answered Oct 10 '22 04:10

David Heffernan