delphi - 线程化、带有 SendMessage 消息传递的 com+ 调用

标签 delphi winapi com delphi-7

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

这样我就可以显示模式窗口并执行其他操作。

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

我认为发生这种情况是因为主 SendMessage 正在使用中,并且 com+ 调用需要 Windows 消息传递来完成其任务。

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

谢谢

编辑:

  1. 主(UI)2.一个线程

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

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

    1. 主要
    2. 主要
    3. 主要
    4. CoInitializeEx(nil, COINIT_MULTITHREADED);
    5. 是的。

最佳答案

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

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

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

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

关于delphi - 线程化、带有 SendMessage 消息传递的 com+ 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9769673/

相关文章:

c++ - WinAPI 设备通知 - 未进入消息循环

C++/CLI 与 COM——哪个更好?

delphi - 带有 OpenSSL(无证书)的简单 TIdTCPServer 具有 "HandShake Failure"和 "No Shared Cipher"

windows - 如何启用 'Microsoft.Windows.Common-Controls'进行特定控制?

c++ - 子类化后编辑控件无法获得焦点或设置文本

c++ - 如何在运行时加载 COM DLL

c# - 是否可以在不注册自身的情况下引用 COM DLL?

delphi - 如何编写Delphi程序来控制CPU风扇速度并监控温度?

c++ - 如何获取有关 Webbrowser 控件实例或 IE Webbrowser 的滚动条的信息?

delphi - 开发Delphi VCL组件时使用什么基类?