线程,com +调用SendMessage消息

时间:2012-03-19 11:53:53

标签: delphi winapi com delphi-7

我有一个应用程序,它创建一个通过Windows消息与主UI通信的线程。它只是将消息发送到主应用程序线程并收到状态。

这样我就会显示模态窗口并做其他事情。

问题是当我必须显示一个调用com +服务器的表单时。 这样我就得到了OLE错误8001010D:由于应用程序正在调度输入同步调用,因此无法进行传出呼叫。

我认为这是因为主要的SendMessage正在使用中,而且com +调用需要Windows消息传递才能完成任务。

无论如何,在delphi中我无法从线程中显示表单,但是我如何解决问题...?

由于

编辑:

  1. MAIN(UI)2。A THREAD
  2. 一个。线程(2)向主线程发送消息(1) B.主线程(1)接收msg并在让它返回线程之前    它显示窗口。 C.主线程中的模态窗口想要进行com +调用,发生上述错误。


    1. 模态窗口在哪个线程? 2. COM调用来自哪个线程? 3.实例化COM对象的哪个线程? 4.后台线程是否使用STA初始化? 5.模态表单是否从SendMessage处理程序中显示? - Roman R. 2分钟前

      1. MAIN
      2. MAIN
      3. MAIN
      4. CoInitializeEx(零,COINIT_MULTITHREADED);

1 个答案:

答案 0 :(得分:12)

问题原因来自COM在处理SendMessage请求时无法封送传出的COM调用。出现的错误是RPC_E_CANTCALLOUT_ININPUTSYNCCALL (0x8001010D),您指的是。 我的印象是,这仅适用于SendMessage调用,这些调用是传入的线程间COM请求的一部分,但这可能是错误的假设。

您的典型解决方法是将SendMessage替换为PostMessage,然后等待同步对象,事件或信号量。这样你的调用者后台线程就不会保存消息来同步调用并自动等待,在主线程上通过常规消息队列调度消息并最终到达同一个处理程序。

作为奖励,您可以选择安全地终止后台线程。如果当前它被SendMessage API锁定,等待模态对话框,建议的更改将允许您从主线程发信号通知同步对象并让它继续运行,例如如果你想安全地终止它。

另一种解决方案可能是调用InSendMessage函数,如果是,则推迟模态UI,例如再次向self发送一条消息,以便稍后在另一个消息处理程序中弹出该表单。