Solved

Clearing the Message Queue of a specific message

Posted on 1998-05-13
20
1,762 Views
Last Modified: 2013-12-03
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?
0
Comment
Question by:gvg
  • 8
  • 6
  • 4
  • +2
20 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 1401423
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
 
LVL 11

Expert Comment

by:alexo
ID: 1401424
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
 
LVL 1

Author Comment

by:gvg
ID: 1401425
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
 
LVL 22

Expert Comment

by:nietod
ID: 1401426
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
 
LVL 1

Author Comment

by:gvg
ID: 1401427
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
 
LVL 22

Expert Comment

by:nietod
ID: 1401428
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
 
LVL 1

Author Comment

by:gvg
ID: 1401429
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
 
LVL 22

Expert Comment

by:nietod
ID: 1401430
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
 
LVL 1

Author Comment

by:gvg
ID: 1401431
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
 
LVL 22

Expert Comment

by:nietod
ID: 1401432
Sure.  I didn't answer because I figured you might get a solution more along the lines of what you already developed.  I
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 15

Expert Comment

by:Tommy Hui
ID: 1401433
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
 
LVL 22

Expert Comment

by:nietod
ID: 1401434
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
 
LVL 1

Expert Comment

by:lekshmikr
ID: 1401435
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
 
LVL 1

Author Comment

by:gvg
ID: 1401436
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
 
LVL 1

Author Comment

by:gvg
ID: 1401437
lekshmikr:  I can't see how this answers may question about emptying the queue without processing a message sent by SendMessage.
0
 
LVL 22

Accepted Solution

by:
nietod earned 150 total points
ID: 1401438
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
 
LVL 11

Expert Comment

by:alexo
ID: 1401439
Nietod will be gone for a couple of days so it can take some time.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1401440
Oops.  Spoke too soon :-)

0
 
LVL 22

Expert Comment

by:nietod
ID: 1401441
Thanks, though.  I leave in 8 hours.  
0
 
LVL 11

Expert Comment

by:alexo
ID: 1401442
Bon voyage.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In this article, I will show how to use the Ribbon IDs Tool Window to assign the built-in Office icons to a ribbon button.  This tool will help us to find the OfficeImageId that corresponds to our desired built-in Office icon. The tool is part of…
This article describes a technique for converting RTF (Rich Text Format) data to HTML and provides C++ source that does it all in just a few lines of code. Although RTF is coming to be considered a "legacy" format, it is still in common use... po…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Delivering innovative fully-managed cloud services for mission-critical applications requires expertise in multiple areas plus vision and commitment. Meet a few of the people behind the quality services of Concerto.

948 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now