Clearing the Message Queue of a specific message

I have a window that receives a lot of userdefined messages which are user defined ( WM_USER + X ).  When I process one of this messages I want to clear the message queue of all other instances of the same message.  
This I have been doing buy calling

PeekMessage( &msg, this, messageID, messageID, PM_REMOVE );

This works fine but with one exception.
The exception is that a another thread SENDS a message to the window and PeekMessage takes the message processis it.  This would be ok if the message sent by the other tread wasn't a message forcing the window to close ( WM_CLOSE ).  Now when the PeekMessage function returns the window has been destroyed.

So the question is this.  Can I clear the queue of a specific message in a diffrent way or can a force PeekMessage not to process other messages?
LVL 1
gvgAsked:
Who is Participating?
 
nietodConnect With a Mentor Commented:
What thui suggested and what I suggested in my second suggestion, is that you use a semaphore (I mean an ordinary flag, not a thread processing OS created semaphore) to indicate when these messages should be ignored and when they should be actually handled.  

Actually a simple semaphore may be inadequite for this,   That is why I suggested a "system of semaphores".  The reason I say that a system is needed, is that you might have a group of messages in the queue that you are trying to ignore and then more come in that you should respond to.  So you could do something where you timestamp the messages.  Say put a serial number (a intenger that you keep incrementing) in one of the message parameters.  Then you can ignore all the messages with serial numbers below a certain value.  That's a poor explanation.  I can give a better one if you are interested.

The more I think about it the more it seems like it should be handled with an event though.  But I can elaborate on the other.
0
 
nietodCommented:
There are some indirect solutions that i can think of.  

First of all, could you just post the WM_CLOSE message instead of sending it?

Could you use some sort of system of semaphores so that these messages can be removed from the queue normally, but are then ignored?

Finally, if this is a 16 bit app, you could try using WM_NOYIELD | PM_REMOVE.  This probably will not help in a 32 bit app, but you could try.
0
 
alexoCommented:
I must be missing something.  When you SendMessage() a message, it is not posted to the message queue but passed directly to the window procedure (bypassing the queue).
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
gvgAuthor Commented:
The problem is that the parent window is running in a diffrent thread and it needs the child to destroy before the parent can destroy it self.  Therefore the parent sends the message.
I could Post the message and wait for it to be processed by waiting for a semaphore but this could take some time because all other messages in the queue which arrived before the CLOSE REQUEST must be processed first.
I can not use PM_NOYIELD because it is obsolete in WIN32
0
 
nietodCommented:
Can I ask what the message is and why there are multiple ones when you only want one?  (I'm thinking there might be a way around this.)
0
 
gvgAuthor Commented:
Ok, Thread A is the main UI thread.  Thread B is an analysis thread that does realtime analysis.  Thread B owns a window to display results.  Thread B also runs on very low priority.  Now when something changes in the data ( lot of diffrent things ) thread A POSTS thread B notifycation about it.  Let's say for example that the time changes and thread A posts a TimeChangeNotify.  Now since thread B is low priority it doesn't respond right away so thread A gets an other time change and notifyes thread B again.  A notify can happen from once per hour to 20times per second.  Ok now thread B finally gets to work.  But it doesn't want to process multiple messages of the same kind so it processes only one notify of each kind.  To do this i peek the message queue and remove multiple instances of the same message but this has the effect as descriped before.
0
 
nietodCommented:
This is an area I am not too familar with, but you probably could use an event rather than a message for this.  Depending on how thread B is written this might be less of a burden on the system.  Thread A wouls signal the event object when it needs a recalculate.  It coult potentially signal multiple times before the recalculate occurs.  That's not problem.  Thread B would wait on the object and would run sometime after it is signaled.

Are you familar with events?
0
 
gvgAuthor Commented:
Yes I am familar with events.  But thread B must be running in the message loop since it must handle all messages for the analysis window like, mouse messages and other stuff and I can't wait for both messages and events.
0
 
nietodCommented:
That is a very common situation.  That is why MsgWaitForMultipleObjects() exists.  It combines the logic of GetMessage() and WaitForObject() into one procedure.  Thie nice thins is that when there are not messages and no signaled objects, then the thread will not take processor time.  When either of these things occur, your thread runs.
0
 
gvgAuthor Commented:
Ok, this is a possible solution but quite trick in programming ( considering how I do this now )since I must override the CWinThread Run function.  If I implement this in this way I will probably also get faster code since events are probably faster than messages.
It would still be nice if I could figure out the original way to do this if anyone knows how to do that.  
Nietod: I will add comment to this question when I am ready to award you with points.  ( That is if I don't get better solution ) THX.

0
 
nietodCommented:
Sure.  I didn't answer because I figured you might get a solution more along the lines of what you already developed.  I
0
 
Tommy HuiEngineerCommented:
Why not use flags in your second thread B to keep track of whether or it is doing something or not?

  MYHandlerForSomeMessage()
  {
    if (m_HandlingThisMessageAlready)
      return; // Ignore because I already am doing this
    m_HandlingThisMessageAlready = TRUE;
    // Do stuff here
    m_HandlingThisMessageAlready = FALSE;
  }


0
 
nietodCommented:
Yeah, that is what I suggested in my first comment.  We focused on the first and last suggestions and never mentioned this one again
0
 
lekshmikrCommented:
The PostMessage function places (posts) a message in the message queue associated with the thread that created the specified window and then returns without waiting for the thread to process the message. Messages in a message queue are retrieved by calls to the GetMessage or PeekMessage function.

0
 
gvgAuthor Commented:
I have desided how I am going to do this.  I can't see how thui's suggjestion works since messages are not handled recursivly. ( maybe I just don't get it )
What I did is I POSTED a message as nietod suggjested in his first comment.  With the message I send an event which is signaled when thread B has destroyed it's window.  Then thread A continues and destroys its window which was a parent window of threads B window.  This works fine.
On the other hand, I will change this later so that thread B receives events instead of messages as nietod suggjested.  I think this will be a lot faster and safer.

nietod you can answer the question now and I will give you a grade, probably a B since you couldn't tell me how to empty the queue, but B is better than nothing.
0
 
gvgAuthor Commented:
lekshmikr:  I can't see how this answers may question about emptying the queue without processing a message sent by SendMessage.
0
 
alexoCommented:
Nietod will be gone for a couple of days so it can take some time.
0
 
alexoCommented:
Oops.  Spoke too soon :-)

0
 
nietodCommented:
Thanks, though.  I leave in 8 hours.  
0
 
alexoCommented:
Bon voyage.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.