Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Context menu disappears with Word automation

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.

like image 412
The_Fox Avatar asked Jun 01 '10 12:06

The_Fox


1 Answers

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. :(

like image 200
Leo Davidson Avatar answered Nov 02 '22 09:11

Leo Davidson