Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to make a Message Only Window

0.00/5 (No votes)
12 Aug 2004 1  
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:

  1. Make it inherit from CWnd, even if it means you multiply inherit.
    //
    
    class CMyMessageOnlyWindowClass : public CWnd
    //
  2. 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);
    //
  3. 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);
  4. Or use something easier like:
    const UINT MY__MESSAGE = WM_USER+14;
  5. 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); 
    }
  6. 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()
  7. 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).

  8. 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?

  1. 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."
  2. Multiple Inheritance: When multiply inheriting, the CWnd needs to come first, for example;
    class CMyMessageOnlyWindowClass : public CWnd, public COtherClass
  3. That's about it, remember: you can't view (see) this window!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here