具有隐藏窗口的线程的线程消息循环?
我有一个 Delphi 6 应用程序,它有一个线程专用于与使用 SendMessage() 和 WM_COPYDATA 消息与外部程序交互的外部应用程序进行通信。因此,我使用 AllocateHWND() 创建一个隐藏窗口来满足该需要,因为由于 SendMessage() 函数仅接受窗口句柄而不接受线程 ID,因此线程消息队列将无法工作。我不确定要在线程 Execute() 方法中放入什么内容。
我假设如果我使用 GetMessage() 循环或创建一个带有 WaitFor*() 函数调用的循环,线程将阻塞,因此线程的 WndProc() 将永远不会处理来自外部程序的 SendMessage() 消息正确的?如果是这样,放入 Execute() 循环的正确代码是什么,该循环不会不必要地消耗 CPU 周期,但一旦收到 WM_QUIT 消息就会退出?如有必要,我总是可以使用 Sleep() 进行循环,但我想知道是否有更好的方法。
I have a Delphi 6 application that has a thread dedicated to communicating with a foreign application that uses SendMessage() and WM_COPYDATA messages to interface with external programs. Therefore, I create a hidden window with AllocateHWND() to service that need since a thread message queue won't work due to the SendMessage() function only accepting window handles, not thread IDs. What I'm not sure about is what to put in the thread Execute() method.
I assume that if I use a GetMessage() loop or a create a loop with a WaitFor*() function call in it that the thread will block and therefore the thread's WndProc() will never process the SendMessage() messages from the foreign program right? If so, what is the correct code to put in an Execute() loop that will not consume CPU cycles unnecessarily but will exit once a WM_QUIT message is received? I can always do a loop with a Sleep() if necessary but I'm wondering if there is a better way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
AllocateHWnd()
(更具体地说,MakeObjectInstance()
)不是线程安全的,因此您必须小心使用它。最好直接使用CreatWindow/Ex()
(或者使用AllocateHWnd()
的线程安全版本,例如DSiAllocateHwnd()
。在任何在这种情况下,
HWND
与创建它的线程上下文相关联,因此您必须在Execute()
方法内创建和销毁HWND
,而不是在线程的构造函数/析构函数中。此外,即使使用SendMessage()
向您发送消息,它们也来自另一个进程,因此您的不会处理它们。 >HWND
直到其所属线程执行消息检索操作,因此线程需要自己的消息循环。您的 Execute() 方法应如下所示:
或者:
AllocateHWnd()
(more specifically,MakeObjectInstance()
) is not thread-safe, so you have to be careful with it. Better to useCreatWindow/Ex()
directly instead (or a thread-safe version ofAllocateHWnd()
, likeDSiAllocateHwnd()
.In any case, an
HWND
is tied to the thread context that creates it, so you have to create and destroy theHWND
inside yourExecute()
method, not in the thread's constructor/destructor. Also, even thoughSendMessage()
is being used to send the messages to you, they are coming from another process, so they will not be processed by yourHWND
until its owning thread performs message retrieval operations, so the thread needs its own message loop.Your
Execute()
method should look something like this:Alternatively:
这是一个不需要 Classes.pas 的循环,仅依赖于 System.pas 来实现一些辅助函数、Windows.pas 来实现 Win32 API 函数以及 Messages.pas 来实现 WM_ 常量。
请注意,这里的窗口句柄是从工作线程创建和销毁的,但主线程会等待工作线程完成初始化。您可以推迟此等待,直到稍后真正需要窗口句柄时,这样主线程可能会同时执行一些工作,而工作线程会自行设置。
Here is a loop that doesn't require Classes.pas and relies solely on System.pas for some auxiliary functions, Windows.pas for Win32 API functions and Messages.pas for the WM_ constants.
Please note that the window handle here is created and destroyed from the worker thread, but the main thread waits until the worker thread completes the initialization. You can postpone this wait until a later moment, when you actually need the window handle, so the main thread may do some work in the meanwhile, while the worker thread sets itself up.