delphi 2006中的postthreadmessage和peekmessage问题
我创建了一个多子应用程序。应用程序窗口 (W[n]: TMyWindows) 都是相同的,并且都有一个与其关联的私有对象类实例 (E: TMyObject)。 子窗口通过该对象生成一些消息。我在主应用程序中创建了两个线程,它们根据消息的内容处理这些消息。例如,让我们进行以下异步调用:
W[1].E.Service(thread1service)
W[2].E.Service(thread2service)
TMyObject.Service(servicetype) 现在
case servicetype of
thread1service: PostThreadMessage(thread1id,...);
thread2service: PostThreadMessage(thread2id,...);
end;
,在每个线程的执行方法中我都有类似的内容:
while not terminated do
begin
...
if peekmessage(msg,0,thread1message_1,thread1message_n,pm_remove) then
process message
do other things;
end
一切顺利,除了第二个线程没有收到任何消息。 你知道为什么吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我会检查以确保您提供给
PeekMessage()
的范围有效。尝试放入零来接收所有消息,如下所示:如果这不起作用,我会检查
PostThreadMessage()
函数的结果...可能是线程还没有调用PeekMessage()
,这就是提示窗口为您创建消息队列的原因。如本文中所述(在“备注”),您可以检查
PostThreadMessage()
的调用结果,如果失败则检查Sleep()
,或者使用事件向主线程发出信号子线程已准备好接收消息。HTH,
N@
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:If that doesn't work, I would check the result of the
PostThreadMessage()
function... It may be that the thread hasn't calledPeekMessage()
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()
, andSleep()
if it fails, or use an event to signal to the main thread that the child thread is ready to receive messages.HTH,
N@
所以,我不得不放弃,因为我没有找到任何合理的解释。
我决定使用带有事件信号的关键部分来发送消息,以告诉工作线程它们有消息要处理。不幸的是,这意味着主线程必须在发送新消息之前检查工作线程是否处理任何消息。
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.
我知道这是一个老问题,但我的代码中刚刚遇到了类似的问题。我们在 Win 7 64 位上运行 Delphi 2006,相关代码涉及一个 DLL 通过 peekmessage/postthreadmessage 与单独的应用程序进行通信。
我最终设法将问题追溯到向应用程序或 Delphi 授予管理员权限。兼容模式也会导致问题浮出水面,因为它需要授予管理员权限。如果授予管理员权限,则管理线程可以与非管理线程通信,但非管理线程无法将消息发送回具有管理权限的线程。非管理应用程序上的 PostThreadMessage 调用报告成功,但该消息从未出现在目标应用程序的消息队列中。
我还没有解决这个问题,但幸运的是能够在正常模式下运行该应用程序,所以除了在追查它时浪费时间之外,这不是一个问题。
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.