上下文菜单随Word自动化消失

The*_*Fox 16 delphi automation ole contextmenu ms-word

当我在OleContainer(inplace)中编辑Word文档并切换到另一个Word文档然后切换回来时,我再也无法使用我的rightmouse按钮了.上下文菜单不会显示.

这发生在Word 2000上,而不是Word 2007上(我不知道其他版本).

我怎样才能摆脱这种行为?

如何重现:

  • 创建一个新的VCL应用程序
  • 添加菜单栏
  • 添加TOleContainer,AlClient,AllowInPlace和AllowActiveDoc True.
  • 使用TOleContainer,插入Word 97-2003文档
  • 将菜单项"关闭"添加到菜单栏,在其事件处理程序中添加OleContainer1.DestroyObject,以便您可以停止编辑
  • 运行此应用程序,双击OleContainer,使其进入editmode
  • 现在打开Word 2000
  • 切换回您的应用程序,上下文菜单将不再起作用.

编辑:我在以下系统上重现了上述行为(使用Citrix):

Windows Server 2003企业版
5.2版(Build 3790.srv03_sp2_rtm.070216-1710:Service Pack 2)

Microsoft Word 2000(9.0.6926 SP-3)

我使用Delphi 7(build 8.1)来创建应用程序.

Leo*_*son 4

通过 ActiveX 托管 Office 应用程序时,您会发现某些 Office 应用程序的某些版本对于获取窗口激活更改的通知非常敏感,这尤其会影响它们的上下文菜单。

基本上,如果您在他们失去或获得焦点时以及顶级窗口获得或失去焦点时不告诉他们(即使他们在窗口中的子控件没有获得焦点),那么他们可能会陷入混乱。

这是我长期以来一直在努力解决的问题,尤其是当你必须告诉应用程序他们比你更了解的事情时(比如当他们直接失去或获得焦点时......或者当他们创建一个弹出菜单,该菜单将焦点从它们身上移开,并且必须以不同于其他某些应用程序/窗口的方式处理焦点,这取决于您的猜测......呃。

无论如何,Office 应用程序应该公开 IOleInPlaceActiveObject 接口,并且您应该确保调用其 OnFrameWindowActivate 方法来告诉它有关激活/停用的信息。

根据记忆,快速浏览一下我自己的托管 Office 代码,这是最重要的事情之一。这也是一件很容易被忽视的事情,认为“不,这并没有那么重要......为什么会有人那么关心窗口是否处于活动状态?” 您可能认为这只会导致一些小的外观问题(例如在不活跃时显得活跃),但它可能会导致整个事情锁定或崩溃。相信我,Office 太关心这些事情了!我的印象是,在 Office 的背后,仍然有一个非常古老的单线程设计,来自协作多任务时代的沉闷,当它的两个窗口似乎同时处于活动状态时,它会变得非常混乱。

抱歉,除了指出这个方向之外,我无法提供更多建议...编写 ActiveX 主机是一门黑术(所有文档都是针对托管,而不是主机:( ),这是我获得自己的代码的唯一方法工作经历了数月的反复试验和大量的调试。不幸的是,这是一场噩梦。

最后一条建议:不要害怕为特定应用程序硬编码拼凑。这就是 IE 本身所做的,通过注册表设置来控制哪些组合应用到哪些内容(我怀疑代码中还硬编码了一些)。ActiveX 是一个定义不明确的混乱,各种控件都有自己的怪癖和错误,并且不可能编写一个与所有控件一起工作的干净、通用的主机。(修复一个问题的更改会破坏另一个问题。)您还会发现,只有按照与 IE 相同的顺序尝试接口时,某些东西才有效,因为它们只用 IE 进行过测试;做事稍有不同,结果就会分崩离析。:(