1
1
与其从两个线程访问COM对象,不如在第二个线程中显示消息对话框。VCL不是线程安全的,但Windows是。
|
2
1
这里真正的问题是Office应用程序不适合多线程使用。因为可以有任意数量的客户端应用程序通过COM发出命令,所以这些命令被序列化为调用并逐个处理。但有时Office处于不接受新呼叫的状态(例如,当它显示模式对话框时),您的呼叫将被拒绝(给出“呼叫被被叫方拒绝”-错误)。 See also the answer of Geoff Darst in this thread. 您需要做的是实现一个IMessageFilter并处理被拒绝的调用。我是这样做的:
messagefilter必须与发出COM调用的线程在同一线程上注册。我的messagefilter实现将在显示标准oleuibusy对话框前等待10秒。通过此对话框,您可以选择重试被拒绝的调用(在保存的情况下)或切换到阻塞应用程序(Excel显示模式对话框)。 阻塞20秒后,将启用取消按钮。单击“取消”按钮将导致保存调用失败。 因此,不要再纠结于线程,而是实现messagefilter,这就是 处理这些问题。 编辑: 上面的修复“Call was rejected by Callee”错误,但是您有一个挂起的保存。我怀疑保存会弹出一个需要您注意的弹出窗口(您的工作簿已经有文件名了吗?)。如果是弹出窗口,请尝试以下操作(不在单独的线程中!):
还可以尝试使用application.visible:=true进行调试;如果有弹出窗口,您将看到它们发生更改,并采取措施防止将来发生这些更改。 |
3
0
试着打电话 CoInitializeEx 具有 COINIT_MULTITHREADED 由于msdn声明: 多线程(也称为自由线程)允许在任何线程上运行对该线程创建的对象方法的调用。 |
4
0
“封送”可以使用以下方法完成从一个线程到另一个线程的接口 CoMarshalInterThreadInterfaceInStream 要将接口放入流中,请将该流移动到另一个线程,然后使用 CoGetInterfaceAndReleaseStream 从流中获取接口。看见 here for an example 在德尔菲。 |
5
0
拉尔斯的回答是正确的。他的建议的另一种选择是使用git(全局接口表),它可以用作接口的跨线程存储库。 看到这个所以线程 here 对于与Git交互的代码,我发布了一个Delphi单元,它提供了对Git的简单访问。 只需从主线程将Excel接口注册到Git中,然后使用getInterfaceFromGlobal方法从TofficeChangThread线程中获取对该接口的单独引用。 |
Some1Else · 函数在Delphi中重新创建TForm 2 年前 |
Agmcz · Delphi安卓库。so未安装(AAB) 2 年前 |
nader · 如何使用delphi在web上提交表单 6 年前 |
kwadratens · Delphi中的卡方分布函数代码 6 年前 |
user9672569 · 如何在完整的位图图像中绘制阴影效果? 6 年前 |
mmmm · MSBuild(用于Delphi)Make-like功能 6 年前 |