Introduction
An article on making a message only window class and why this is a useful thing to do.
Background
According to Microsoft:
A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.
Simpler: You can send messages (PostMessage
and SendMessage
) to it. If you have a class which is derived from it, you can have it reacting to messages from other areas of code in a similar fashion to a normal window.
Benefits of using a message only window
- Free queue for messages.
What do you mean?
If your system is message based from some sort of external IO say, and you are in need of a queuing facility, then your application can use PostMessage
to post messages to the hidden window. These messages will be queued in the normal Windows message queue.
- Inter/intra process communication
What do you mean?
Another part of your application (or an external application) can handle the arrival of these messages.
How do I make one?
It is pretty easy actually.
In the class that is to deal with the messages, follow this procedure:
- Make it inherit from
CWnd
, even if it means you multiply inherit.
class CMyMessageOnlyWindowClass : public CWnd
- In the constructor or some other useful initialization type function, use the following code (change where needed).
CString wnd_class_name = ::AfxRegisterWndClass(NULL);
BOOL created = this->CreateEx(0,wnd_class_name,
"CMyMessageOnlyWindowClass",0 ,0 ,0 ,0 ,0 ,HWND_MESSAGE,0);
- Either register your own Windows message:
const CString THIS_IS_MY_MESSAGE_STRING = "THIS_IS_MY_MESSAGE_STRING";
const UINT MY_REGISTERED_MESSAGE =
::RegisterWindowMessage(THIS_IS_MY_MESSAGE_STRING);
- Or use something easier like:
const UINT MY__MESSAGE = WM_USER+14;
- Create your message handling function in your .h and .cpp files.
.h first
afx_msg LRESULT DealWithMyRegisteredMsg(WPARAM wParam, LPARAM lParam);
or
afx_msg LRESULT DealWithMyMsg(WPARAM wParam, LPARAM lParam);
Now, the cpp file
LRESULT CMyMessageOnlyWindowClass::DealWithMyRegisteredMsg(WPARAM wParam,
LPARAM lParam)
{
AfxMessageBox("Chris is ready for a beer");
return LRESULT(true);
}
or
LRESULT CMyMessageOnlyWindowClass::DealWithMyMsg(WPARAM wParam,
LPARAM lParam)
{
AfxMessageBox("Chris is ready for a beer");
return LRESULT(true);
}
- Add the message map:
BEGIN_MESSAGE_MAP(CMyMessageOnlyWindowClass, CWnd)
ON_REGISTERED_MESSAGE(MY_REGISTERED_MESSAGE, DealWithMyRegisteredMsg)
END_MESSAGE_MAP()
- Now, go back to your .h file, and at the very end of your class - after all the functions and variables and so on (but before the �
};
�), � stick:
DECLARE_MESSAGE_MAP()
This says �I will be using a message map in my class� (well, we have just defined it).
- Now, when you want to post to this window, all you need is the handle to it�or a pointer to it, and you will find it should behave just like a normal window, only you can�t see it etc.
What else do I need to know?
- FindWindow: If you want to use
FindWindow
, you need to pay attention to the MSDN which says� "To find message-only windows, specify HWND_MESSAGE in the hwndParent
parameter of the FindWindowEx
function. In addition, FindWindowEx
searches message-only windows as well as top-level windows if both the hwndParent
and hwndChildAfter
parameters are NULL."
- Multiple Inheritance: When multiply inheriting, the
CWnd
needs to come first, for example; class CMyMessageOnlyWindowClass : public CWnd, public COtherClass
- That's about it, remember: you can't view (see) this window!