Guaranteeing uniqueness
You may have already discovered a problem that is identical for both constant
messages and registered messages. What if you choose a nice, obvious name like
"UWM_RESET_VIEW" as the string name of the message, and some
other programmer has also chosen another nice, obvious, simple name for his or
her DLL, such as "UWM_RESET_VIEW". Have we really made progress?
No.
But there is a way around it. There is a program which is part of the SDK,
called GUIDGEN. What this program does is create a unique 128-bit binary
value. Each time you create a new Globally Unique
IDentifier, a GUID, you can be sure that it is really, truly, unique.
It is not only unique for you, it is unique for everyone, everywhere, all the
time. It incorporates the time and date, the MAC address from your network card
(and if you don't have a network card, it uses another method, which has something
like one chance in 263 of conflicting with another GUID), and a bunch
of other information. Therefore, there is no way, short of explicit collusion
between two programmers, that they will use the same GUID.
All my registered window messages use a GUID as part of their name.
When you run GUIDGEN, you get a screen that looks like this:
Select option 4, "Registry format". Click the "Copy" button.
A copy of the string as shown in the Result box will be placed in the clipboard.
Then go to your editor and type something like
#define UWM_RESET_VIEW_MSG _T("UWM_RESET_VIEW-<paste>")
which creates a name like
_T("UWM_RESET_VIEW-{4E7F6EC0-6ADC-11d3-BC36-006067709674}")
I actually have a macro
#define DECLARE_USER_MESSAGE(name) \
static const UINT name = ::RegisterWindowMessage(name##_MSG);
which handles most of the hassle for me. While strictly speaking my GUID can
suffice for all my messages, I usually just generate a new GUID for each message.
Any time I want to create an instance of a message, for use in a message table
or for posting, I just do
DECLARE_USER_MESSAGE(UWM_RESET_VIEW)
and, because of my convention of naming the string the same, I get the variable
initialized. Typically these appear in the outer block of each module that uses
the symbols. All I have to make sure is that the header file for DECLARE_USER_MESSAGE
and the header file for the messages I want are both included.
So why do I even bother to put a readable name into the string? The 128-bit
GUID should be sufficient! Well, the truth is that the readable name is totally
redundant and essentially irrelevant. Unless you happen to be using Spy++ to
trace message traffic. In that case, you really, really want to see something
you understand, and 128-bit GUIDs are not really high on the list of easily
readable values. The only reason the readable string is there is for the convenience
of you, the developer. It doesn't matter, otherwise.