Message Management

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.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Computer Science is no more about computers than astronomy is about telescopes.” - E. W. Dijkstra