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

发布于 2024-09-03 12:46:37 字数 761 浏览 1 评论 0原文

当我在 OleContainer(就地)中编辑 Word 文档并切换到另一个 Word 文档然后再切换回来时,我无法再使用鼠标右键。上下文菜单将不会显示。

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

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

如何重现:

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

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

Windows Server 2003 Enterprise Edition
版本 5.2(内部版本 3790.srv03_sp2_rtm.070216-1710:Service Pack 2)

Microsoft Word 2000 (9.0.6926 SP-3)

我使用 Delphi 7(内部版本 8.1)来创建应用程序。

When I am editing a Word document in an OleContainer (inplace) and I switch to another Word document and then I switch back, I cannot use my rightmouse button anymore. The context menu will not show up.

This happens on Word 2000, not on Word 2007 (I don't know about other versions).

How can I get rid of this behaviour?

How to reproduce:

  • Create a new VCL Application
  • Add a menubar
  • Add a TOleContainer, Align alClient, AllowInPlace and AllowActiveDoc True.
  • With the TOleContainer, insert an Word 97-2003 document
  • Add a menuitem 'Close' to the menubar, in its eventhandler, add OleContainer1.DestroyObject, so you are able to stop editing
  • Run this application, doubleclick on the OleContainer so it goes in editmode
  • Now open Word 2000
  • Switch back to your application, the contextmenu will not work anymore.

Edit:
I reproduced above behavior on the following system (using Citrix):

Windows Server 2003 Enterprise Edition
Version 5.2 (Build 3790.srv03_sp2_rtm.070216-1710 : Service Pack 2)

Microsoft Word 2000 (9.0.6926 SP-3)

I used Delphi 7 (build 8.1) to create the application.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

累赘 2024-09-10 12:46:37

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

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

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

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

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

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

。使用注册表设置来控制哪些组合应用到哪些内容(我怀疑一些更多的硬编码到代码中是一个定义不明确的混乱,各种控件都有自己的怪癖和错误,并且不可能编写干净的通用主机)。 (修复一个的更改会破坏另一个。)您还会发现,只有按照与 IE 相同的顺序尝试接口才能工作,因为它们只在 IE 上进行过测试;做一些稍微不同的事情,然后他们就会崩溃:(

When hosting Office apps via ActiveX, you'll find some versions of some Office apps are ridiculously touchy about being informed of window activation changes and this can especially affect their context menus.

Basically, if you don't tell them whenever they lose or gain the focus and also whenever your top-level window gains or loses focus (even if their child control in the window isn't gaining focus), then they can go haywire.

It's something I fought with for a long time and especially frustrating when you're having to tell the applications things that they are in a better position to know than you are (like when they lose or gain the focus directly... or when they create a pop-up menu which takes the focus away from them and has to be handled differently to some other app/window taking the focus, which you are left to divine... Ugh.

Anyway, the Office apps should expose an IOleInPlaceActiveObject interface and you should ensure you call its OnFrameWindowActivate method to tell it about activation / deactivation.

From memory, and a quick look at my own code for hosting Office, that is one of the most important things. It is also an easy thing to overlook, thinking "Nah, it can't matter that much... Why would anything care that much about whether the window is active or not?" You might think it could only lead to some minor cosmetic issues (like appearing active when it isn't) but it can lead to the whole thing locking up or crashing. Trust me, Office cares way too much about such things! I get the impression that under the covers of Office there is still a very old, single-threaded design from the days of co-operative multitasking clunking away and it can get very confused when two of its windows seem to be active at once.

Sorry that I cannot give more advice than just pointing in that direction... Writing ActiveX hosts is a black art (all the documentation is geared towards being hosted, not being the host :( ) and the only way I got my own code to work was through months of trial and error and a hell of a lot of debug-out. It's a nightmare, unfortunately.

One last piece of advice: Don't be afraid to hardcode kludges for particular applications. This is what IE itself does, with registry settings to control which kludges get applied to what (and I suspect some more hardcoded into the code). ActiveX is such a poorly-defined mess that various controls have their own quirks and bugs and it's impossible to write a clean, generic host that works with all of them. (A change that fixes one will break another.) You'll also find things that only work if you try interfaces in the same order that IE does, just because they've only been tested with IE; do things slightly differently and they fall apart. :(

相对绾红妆 2024-09-10 12:46:37

我想知道您是否可以从包含 OLE 容器的表单中捕获任何 Lost Focus 类型事件,此时您可以销毁 OLE 容器中的文档,但将其保留在内存中。然后,在表单的任何 Got Focus 类型事件中,您可以检查是否有该文档;如果是这样,请将其重新加载到 OLE 容器中。

这对你有用吗?

I wonder whether you could catch any Lost Focus type event from the form containing the OLE container, at which time you could destroy the document in the OLE container but keep it in memory. Then, on any Got Focus type event for the form, you could check to see if you have that document; if so, re-load it into the OLE container.

Would that work for you?

青朷 2024-09-10 12:46:37

也许您可以使用组件来调用应用程序。我从来没有遇到过创建自定义组件以通过界面调用单词,然后在菜单上注册特殊命令的问题。在容器中不能在窗体上设计专门的菜单吗?有一些 WordSink Eventets 可以帮助保存和关闭,可以与 word com 对象结合使用。

Maybe you can use a component to invoke the application. I never had a problem creating a custom compoment to invoke word through interfaces and then registering special commands at the menu. In a container can you not design a special menu on the form? There are a few WordSink Evenets that will help in saving and closing that could be used in conjunction with the word com objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文