How to make a Message Only Window






4.86/5 (16 votes)
Aug 13, 2004
2 min read

163563

2733
An article on how to make a message only window.
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) // or ON_MESSAGE(BLAH_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 thehwndParent
parameter of theFindWindowEx
function. In addition,FindWindowEx
searches message-only windows as well as top-level windows if both thehwndParent
andhwndChildAfter
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!