Word 自动化使上下文菜单消失
Posted
技术标签:
【中文标题】Word 自动化使上下文菜单消失【英文标题】:Context menu disappears with Word automation 【发布时间】:2010-06-01 12:44:51 【问题描述】:当我在 OleContainer(就地)中编辑 Word 文档并切换到另一个 Word 文档然后切换回来时,我无法再使用鼠标右键。上下文菜单不会显示。
这发生在 Word 2000 上,而不是 Word 2007(我不知道其他版本)。
我怎样才能摆脱这种行为?
如何重现:
创建一个新的 VCL 应用程序 添加菜单栏 添加一个 TOleContainer,对齐 alClient、AllowInPlace 和 AllowActiveDoc True。 使用 TOleContainer,插入 Word 97-2003 文档 向菜单栏添加一个“关闭”菜单项,在其事件处理程序中添加OleContainer1.DestroyObject
,这样您就可以停止编辑
运行此应用程序,双击 OleContainer 使其进入编辑模式
现在打开 Word 2000
切换回您的应用程序,上下文菜单将不再起作用。
编辑: 我在以下系统上重现了上述行为(使用 Citrix):
Windows Server 2003 企业版 5.2 版(内部版本 3790.srv03_sp2_rtm.070216-1710:Service Pack 2)
Microsoft Word 2000 (9.0.6926 SP-3)
我使用 Delphi 7 (build 8.1) 创建应用程序。
【问题讨论】:
您能说出您使用的是哪些版本和服务包级别(OS、Delphi、Word)吗? 此错误是否在 Citrix 之外发生? @Judah Himango:我在 Citrix 之外没有可用于 Word 2000 的系统,所以很遗憾我无法回答您的问题。 好的。请记住,大约一两年前,我们在 Citrix 中看到了一些奇怪的焦点和窗口激活行为。您可能需要确认此错误是否发生在 Citrix 外部。 【参考方案1】:通过 ActiveX 托管 Office 应用程序时,您会发现某些 Office 应用程序的某些版本在通知窗口激活更改时非常敏感,这尤其会影响它们的上下文菜单。
基本上,如果您在他们失去或获得焦点以及***窗口获得或失去焦点时不告诉他们(即使他们在窗口中的子控件没有获得焦点),那么他们可以搞砸了。
这是我长期以来一直在争论的事情,尤其是当你不得不告诉应用程序他们比你更了解的事情时尤其令人沮丧(比如当他们失去或直接获得焦点时......或者当他们创建一个弹出菜单时,该菜单会将焦点从他们身上移开,并且必须与其他一些获得焦点的应用程序/窗口不同地处理,而你只能靠神来判断......呃。
无论如何,Office 应用程序应该公开一个 IOleInPlaceActiveObject 接口,并且您应该确保调用它的 OnFrameWindowActivate 方法来告诉它有关激活/停用的信息。
凭记忆,快速浏览一下我自己托管 Office 的代码,这是最重要的事情之一。这也是一件很容易被忽视的事情,想着“不,这没关系……为什么会有这么关心窗口是否处于活动状态?”您可能认为它只会导致一些轻微的外观问题(例如在不活跃时显得活跃),但它可能导致整个事情锁定或崩溃。相信我,Office 太在乎这些事情了!我的印象是,在 Office 的掩护下,仍然有一个非常古老的单线程设计,从协作式多任务处理的时代开始,当它的两个窗口似乎同时处于活动状态时,它会变得非常混乱。
很抱歉,除了指出这个方向之外,我无法提供更多建议...编写 ActiveX 主机是一门黑艺术(所有文档都是针对托管,而不是作为主机 :(),并且是我得到我的唯一方法自己的代码要经过几个月的反复试验和大量调试。不幸的是,这是一场噩梦。
最后一条建议:不要害怕为特定应用程序硬编码组合。这就是 IE 本身所做的,通过注册表设置来控制哪些 kludges 应用于什么(我怀疑在代码中还有一些硬编码)。 ActiveX 是一个定义不清的混乱,以至于各种控件都有自己的怪癖和错误,并且不可能编写一个干净、通用的主机来处理所有这些。 (修复一个更改会破坏另一个更改。)您还会发现只有按照与 IE 相同的顺序尝试接口才能起作用的东西,只是因为它们仅在 IE 上进行过测试;做事稍有不同,他们就会分崩离析。 :(
【讨论】:
有点晚了,但是谢谢,成功了!这也解决了 Word 2007 在我们的应用程序和 Word 之间切换时无法使用菜单的问题。 (我通过调用 uiActivate 解决了这个问题,但这更好更快)。 PS:你是对的关于黑艺术的事情,你不想知道我们从客户那里得到了多少完全无法重现的错误报告。 @The_Fox,很高兴它有用!【参考方案2】:我想知道您是否可以从包含 OLE 容器的表单中捕获任何 Lost Focus
类型事件,此时您可以销毁 OLE 容器中的文档但将其保留在内存中。然后,在表单的任何Got Focus
类型事件上,您可以检查是否有该文档;如果是这样,请将其重新加载到 OLE 容器中。
这对你有用吗?
【讨论】:
【参考方案3】:也许您可以使用组件来调用应用程序。我从来没有遇到过创建自定义组件以通过接口调用单词然后在菜单上注册特殊命令的问题。在容器中你不能在表单上设计一个特殊的菜单吗?有一些 WordSink 事件有助于保存和关闭,可以与单词 com 对象结合使用。
【讨论】:
以上是关于Word 自动化使上下文菜单消失的主要内容,如果未能解决你的问题,请参考以下文章