1

I created a multichilded application. The application windows (W[n]: TMyWindows) are all the same and all have an private object class instance associated with them (E: TMyObject). The child windows generate through this objects some messages. I have created in the main application two threads which process these messages depending on the content of the messages. For example lets have the following asynchronous calls:

W[1].E.Service(thread1service)
W[2].E.Service(thread2service)

the TMyObject.Service(servicetype) is

case servicetype of
  thread1service: PostThreadMessage(thread1id,...);
  thread2service: PostThreadMessage(thread2id,...);
end;

Now, in the Execute Method of each thread i have something like that:

while not terminated do
begin
 ...
 if peekmessage(msg,0,thread1message_1,thread1message_n,pm_remove) then
      process message
 do other things;
end

All goes fine exept that the second thread doesn't receive any messages. Do you have any idea why?

Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477
zoomz
  • 125
  • 2
  • 10

3 Answers3

1

I would check to make sure that the range you are supplying to PeekMessage() is valid. Try putting zeros in instead to receive all messages, like this:

PeekMessage(msg, 0, 0, 0, PM_REMOVE)

If that doesn't work, I would check the result of the PostThreadMessage() function... It may be that the thread hasn't called PeekMessage() yet, that's what prompts windows to create the message queue for you.

As stated in this article (under "Remarks"), you can either check the result of the call to PostThreadMessage(), and Sleep() if it fails, or use an event to signal to the main thread that the child thread is ready to receive messages.

HTH,

N@

Nat
  • 5,414
  • 26
  • 38
0

I know this is an old question, but I have just had a similar problem in our code. We are running Delphi 2006 on Win 7 64-bit and the code in question involved a DLL communicating to a separate application via peekmessage/postthreadmessage.

I eventually managed to trace the issue down to administrator rights being granted either to the application or to Delphi. Compatibility mode also causes the problem to surface, as it requires admin rights to be granted. If admin rights are granted, the admin thread could communicate to the non-admin thread, but the non-admin thread could not then post a message back to the thread with admin privileges. The PostThreadMessage call on the non-admin app was reporting success, but the message never appeared in the target app's message queue.

I haven't solved the problem, but fortunately was able to run the application in normal mode, so it wasn't an issue other than the lost time in chasing it down.

Matt Allwood
  • 1,448
  • 12
  • 25
0

So, I had to give up as I didn't find any rational explanation.

I've decided to send messages using a critical section with event signaling to tell the working threads that they have a message to process. Unfortunately, this means that the main thread have to check that the working thread processes any message before sending a new one.

zoomz
  • 125
  • 2
  • 10
  • Not necessarily. Give each thread a FIFO queue, protected by a critical section, and add an event to wait on. Signal the event when the FIFO is not empty. – mghie Sep 20 '09 at 08:39
  • I thought about that, but then if the main thread puts to many massages in the queue, the working thread will be forced to process them, and the working thread does some critical tasks in his loop. So if the working thread is processing any message, the main thread just dump the new messages instead of sending them to the working thread. – zoomz Sep 20 '09 at 09:12
  • Sad really, a thread message queue would have been ideal. I'm still wondering why it doesn't work for you. I checked my implementation of this and you don't seem to be doing anything wrong from what you are saying. :( – Nat Sep 22 '09 at 01:03