Click here to Skip to main content
Click here to Skip to main content

About the Windows Message Queue

, 17 Apr 2002
Rate this:
Please Sign up or sign in to vote.
This article is written for the Win32 API programmers on the subject of Windows message queues.
<!-- Download Links --> <!-- Article image -->

Sample Image - queue.gif

<!-- Add the rest of your HTML here -->

Introduction

Everybody knows MFC as the most powerful instrument for developing applications on the Windows system. Its classes are specialized on the entire family of difficult tasks you can imagine and the flexibility of the chosen solutions is remarkable. It's the best approach on developing large software and keeps the programmer away from several kind of detail problems. This should be the greatest advantage when having to deal with a window-based system but...

The Thread

We're not talking about a window-based system here. "The atomic working entity of a program is the thread", says the MSDN book. Among many background details like  stack and paths of execution, it also has to cover the implementation of a message queue. It's not a rule but you will find it on every thread that sustains a window. This is the reason for a very popular confusion: the window has a message queue. Wrong! The message queue belongs to the thread and the messages posted to the window are dispatched to it by the message loop in the thread. I will illustrate this by the program attached to this article.

The Program

Is a console based application; the modeless dialog manages its messages through the console's message queue, so it's not about having two queues at a time. The code offers you a class and the main function.

CConsoleQueue

This class implements the message loop and a primitive system of handling messages. It has the following methods:

RunQueue - runs the classical message loop

  while (GetMessage(&msg, NULL, 0, 0))    // extract the message 
                                          // from the queue
  {
    if (fctMan=(*this)[msg.message])
      fctMan((void *)msg.wParam);
    else
    {
      TranslateMessage(&msg); // necessary to listen the keyboard
      DispatchMessage(&msg);  // message goes to the default 
                              // procedure
    }
  }

EndQueue - terminates the message loop by posting WM_QUIT

  PostMessage(NULL, WM_QUIT, 0, 0);     // message to interrupt
                                        // the loop by returning
                                        // FALSE on GetMessage

RegisterMessageHandler - registers a handler function to a particular message. When the message is received in the message loop, the handler is called. To pass a value for the handle, you should put it through the WPARAM when calling PostMessage.

Note: this could be considered as a skeleton of the reactor concept proposed by The Adaptive Communication Environment (ACE).

RemoveAll - removes all the associations (from the reactor)

main

The purposes of this function are - step by step - the following:

1. Creating a modeless dialog box used to send messages to the queue:

  hWndDialog=CreateDialog(NULL, MAKEINTRESOURCE(IDD_DIALOG_TEST),
    NULL, DialogProcedure); 
  ShowWindow(hWndDialog, SW_SHOW); 

2. Setting a timer on the thread:

  nTimer=SetTimer(NULL, 0, nDelay*1000, TimerProcedure);

3. Registering a handler for an user-defined message:

  queue.RegisterMessageHandler(WM_USER_DEFINED, UserDefined);

4. Running the queue:

  queue.RunQueue();

Behavior

The purpose is to drop WM_TIMER messages in the message queue; each WM_TIMER will print to console a global buffer. If the buffer doesn't modify for the last nKeepQueueSteps WM_TIMERs, the last one will kill the timer and will end the message queue. Modifying the buffer is done in the modeless dialog box by writing in the edit box and pressing "send buffer". Pressing "send user-defined" will post the WM_USER_DEFINED message to the queue.

Final

Observe that calling PostMessage with NULL for the first parameter will drop the message in the current thread's message queue.

Another observation is about setting the timer. This one lives only among the queue's events and is not a window's resource. It belongs to the thread and could reach a window only if is set to and only by a call of DispatchMessage.

The last word is about the message loop. This expression is a source of limitation for the programmer. In fact you could have more message loops in a single thread's execution. To test this, simply multiply the actual content of main in the function's body like this:

  hWndDialog=CreateDialog(NULL, MAKEINTRESOURCE(IDD_DIALOG_TEST), 
    NULL, DialogProcedure); 
  // ...
  cout<<endl<<"program ends here..."<<endl;
  
  hWndDialog=CreateDialog(NULL, MAKEINTRESOURCE(IDD_DIALOG_TEST), 
    NULL, DialogProcedure); 
  // ...
  cout<<endl<<"program ends here..."<<endl;
  
  // ...  
  
  hWndDialog=CreateDialog(NULL, MAKEINTRESOURCE(IDD_DIALOG_TEST), 
    NULL, DialogProcedure); 
  // ...
  cout<<endl<<"program ends here..."<<endl;

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

Share

About the Author

Hans Ruck
Software Developer (Senior)
Europe Europe
No Biography provided

Comments and Discussions

 
GeneralRe: Passing strings using Post Message PinmemberGarth J Lancaster26-Apr-04 1:04 
GeneralRe: Passing strings using Post Message Pinmemberhedonist26-Apr-04 3:24 
GeneralRe: Passing strings using Post Message PinmemberGarth J Lancaster26-Apr-04 12:53 
GeneralRe: Passing strings using Post Message Pinmemberhedonist26-Apr-04 20:54 
GeneralRe: Passing strings using Post Message PinmemberGarth J Lancaster26-Apr-04 21:42 
GeneralRe: Passing strings using Post Message Pinmemberhedonist27-Apr-04 7:01 
GeneralRe: Passing strings using Post Message Pinmemberhedonist27-Apr-04 7:06 
GeneralRe: Passing strings using Post Message PinmemberTom Wright11-Nov-04 11:35 
GeneralRe: Passing strings using Post Message PinmemberGarth J Lancaster11-Nov-04 13:05 
GeneralIt isn't working in an other project PinmemberTPSC2-Mar-04 22:37 
GeneralRe: It isn't working in an other project PinmemberBogdan Rechi3-Mar-04 0:22 
GeneralRe: It isn't working in an other project PinsussAnonymous3-Mar-04 1:13 
GeneralRe: It isn't working in an other project PinmemberTPSC3-Mar-04 1:15 
GeneralRe: It isn't working in an other project PinmemberBogdan Rechi3-Mar-04 2:02 
Questionwhy? PinmemberMr.Prakash27-Feb-04 5:06 
AnswerRe: why? PinmemberBogdan Rechi27-Feb-04 6:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 18 Apr 2002
Article Copyright 2002 by Hans Ruck
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid