65.9K
CodeProject is changing. Read more.
Home

How to make a Message Only Window

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (16 votes)

Aug 13, 2004

2 min read

viewsIcon

163563

downloadIcon

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:

  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!