Click here to Skip to main content
15,891,033 members
Articles / Desktop Programming / MFC
Article

About the Windows Message Queue

Rate me:
Please Sign up or sign in to vote.
3.67/5 (5 votes)
17 Apr 20023 min read 171.7K   1.7K   37   26
This article is written for the Win32 API programmers on the subject of Windows message queues.

Sample Image - queue.gif

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_TIMER
s, 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


Written By
Software Developer (Senior)
Europe Europe
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalshow desktop Pin
amt_alla7-May-04 0:56
amt_alla7-May-04 0:56 
Generalcontrol client resorces Pin
amt_alla6-May-04 9:30
amt_alla6-May-04 9:30 
GeneralRe: control client resorces Pin
Hans Ruck6-May-04 22:52
Hans Ruck6-May-04 22:52 
GeneralRe: control client resorces Pin
amt_alla7-May-04 1:15
amt_alla7-May-04 1:15 
GeneralRe: control client resorces Pin
Hans Ruck7-May-04 1:33
Hans Ruck7-May-04 1:33 
GeneralPassing strings using Post Message Pin
hedonist23-Apr-04 15:06
hedonist23-Apr-04 15:06 
GeneralRe: Passing strings using Post Message Pin
Garth J Lancaster23-Apr-04 15:36
professionalGarth J Lancaster23-Apr-04 15:36 
GeneralRe: Passing strings using Post Message Pin
hedonist23-Apr-04 19:16
hedonist23-Apr-04 19:16 
GeneralRe: Passing strings using Post Message Pin
Garth J Lancaster24-Apr-04 1:20
professionalGarth J Lancaster24-Apr-04 1:20 
GeneralRe: Passing strings using Post Message Pin
hedonist25-Apr-04 21:44
hedonist25-Apr-04 21:44 
Hi 'G',

Too Bad I don't think I'll get a chance to answer your question.Frown | :(
I'm just to lousy.

Talking about lousy, after digesting portion of the info at the wedsite, I went on to try .
I encounter 2 problems .

1st: When I #define UWM_MY_MSG _T("My_MSG-{xxx-xx-x-xxx}") as describe
by the author, I got error " cannot convert from char [43] to unsigned int"
I could overcome this by #define UWM_MY_MSG WM_APP + 1

2nd:
Under the section Passing pointers to Messages, The author advised not to use PostMessage to pass pointer of CString. But Under the comment UWM_LOG_MESSAGE
it mentioned that the CString Object is usually sent through PostMessage.
This confused me. I didn't see the author illustrate how to go about doing that. I've tried both PostMessage and SenMessage to pass CString as pointer
in the lparam.
I used the handle codes describe in OnLogMessage to handle this CString but
got application error.

I think I still need consultation from the expert! Confused | :confused:
Hope it don't take up too much time.

Learner
GeneralRe: Passing strings using Post Message Pin
Garth J Lancaster26-Apr-04 0:04
professionalGarth J Lancaster26-Apr-04 0:04 
GeneralRe: Passing strings using Post Message Pin
hedonist26-Apr-04 2:24
hedonist26-Apr-04 2:24 
GeneralRe: Passing strings using Post Message Pin
Garth J Lancaster26-Apr-04 11:53
professionalGarth J Lancaster26-Apr-04 11:53 
GeneralRe: Passing strings using Post Message Pin
hedonist26-Apr-04 19:54
hedonist26-Apr-04 19:54 
GeneralRe: Passing strings using Post Message Pin
Garth J Lancaster26-Apr-04 20:42
professionalGarth J Lancaster26-Apr-04 20:42 
GeneralRe: Passing strings using Post Message Pin
hedonist27-Apr-04 6:01
hedonist27-Apr-04 6:01 
GeneralRe: Passing strings using Post Message Pin
hedonist27-Apr-04 6:06
hedonist27-Apr-04 6:06 
GeneralRe: Passing strings using Post Message Pin
Tom Wright11-Nov-04 10:35
Tom Wright11-Nov-04 10:35 
GeneralRe: Passing strings using Post Message Pin
Garth J Lancaster11-Nov-04 12:05
professionalGarth J Lancaster11-Nov-04 12:05 
GeneralIt isn't working in an other project Pin
TPSC2-Mar-04 21:37
TPSC2-Mar-04 21:37 
GeneralRe: It isn't working in an other project Pin
Hans Ruck2-Mar-04 23:22
Hans Ruck2-Mar-04 23:22 
GeneralRe: It isn't working in an other project Pin
Anonymous3-Mar-04 0:13
Anonymous3-Mar-04 0:13 
GeneralRe: It isn't working in an other project Pin
TPSC3-Mar-04 0:15
TPSC3-Mar-04 0:15 
GeneralRe: It isn't working in an other project Pin
Hans Ruck3-Mar-04 1:02
Hans Ruck3-Mar-04 1:02 
Questionwhy? Pin
Prakash Nadar27-Feb-04 4:06
Prakash Nadar27-Feb-04 4:06 

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

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