[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1326
  • Last Modified:

PostMessage() Problem

I have a window with a listbox that displays some progress messages from a thread that is running.  The thread basically formats the text into a buffer and then calls PostMessage().  Most of the time this works ok but sometimes the text gets garbled.

In reading the MSDN I located the following:

If you send a message in the range below WM_USER to the asynchronous message functions (PostMessage, SendNotifyMessage, and SendMessageCallback), its message parameters cannot include pointers. Otherwise, the operation will fail. The functions will return before the receiving thread has had a chance to process the message and the sender will free the memory before it is used.

I suspect this is my issue.

Question:  what's the best way to avoid this problem?  My thread has no clue when Windows processes the message and grabs the stuff in the buffer.  I can't use SendMessage because the thread can't wait around all day.

My thought is that I need to implement some sort of a queue in another thread that will accept these calls to output text to the window asynchronously, store the text in the queue, call SendMesasge, then remove the text from the queue.  But that seems (to me at least) to be an overly complicated solution to what I think should be a fairly common problem.

Thanks in advance...
0
jhance
Asked:
jhance
  • 2
  • 2
  • 2
1 Solution
 
jkrCommented:
Stupid idea - why not using 'GlobalAddAtom()' for that purpose and post the atom via the message parameters? You can delete the atom after processing. A more universal way could indeed be e.g. a std::queue<string> secured by a CRITICAL_SECTION that sync's the access.
0
 
jhanceAuthor Commented:
jkr,

Thanks...  But I'm unfamiliar with GlobalAddAtom().  I see what it says in the MSDN docs but I'm unclear how this would work in solving the problem above.  Specially, how would using this help.  And how would you delete it (or WHO would delete it after "processing"?

Maybe a quick sample?
0
 
jkrCommented:
I haven't used that since Win 3.1, so I am not really sure how that works now, but the idea would be

//in the thread

LPSTR test = "test";

ATOM a = GlobalAddAtom(test);
PostMessage(WM_YOURMESSAGE,hWnd,(WPARAM)a,0);

The problem probably is that you cannot send that directly to the listbox but will have to translate it using 'GlobalGetAtomName()', which leaves you with the same problem, except if you can use a 'SendMessage()' in the receiving WindowProc... thus said, I am starting to wonder whether this idea is even stupider than I thougt.
0
Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

 
jhanceAuthor Commented:
I think it solves one problem but creates another.  

It will prevent the data buffer of the string to be written from being deleted or overwritten before it's output to the screen but finding and cleaning up all the left over atoms will be another problem.  You couldn't do it right after the PostMessage because you'd be right back where you started, namely the atom could be gone by the time the message loop processed the message that said to output it...

I'm not averse to implementing a queue/thread to do this, I was just hoping that there was some trick that every Windows programmer but me knew about that solved this...
0
 
AlexFMCommented:
>> I can't use SendMessage because the thread can't wait around all day.
Do you post message to your own program? In this case you must ensure that it always ready to handle messages and doesn't execute long operations (seconds, days...) without handling message queue. This is basic requirement to any program.
Assuming that message target works properly, you can use SendMessage from a worker thread. To prevent deadlock, it is possible to use SendMessageTimeout.
0
 
AlexFMCommented:
However, classic solution is some string container with critical section. If your data is list of separate messages and not stream, this can be simple list<string>, and not queue. Thread adds new string to this list and posts message to main thread. Main thread reads all strings from the list and clears it. If list is empty, main thread does nothing - pretty simple.
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 2
  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now