Подтвердить что ты не робот

Контекстное меню исчезает с помощью автоматизации Word

Когда я редактирую документ Word в OleContainer (inplace), и я переключаюсь на другой документ Word, а затем переключаюсь обратно, я больше не могу использовать свою правую кнопку. Контекстное меню не будет отображаться.

Это происходит в Word 2000, а не в Word 2007 (я не знаю о других версиях).

Как я могу избавиться от этого поведения?

Как воспроизвести:

  • Создайте новое приложение VCL
  • Добавить строку меню
  • Добавить TOleContainer, Align alClient, AllowInPlace и AllowActiveDoc True.
  • С помощью TOleContainer вставьте документ Word 97-2003
  • Добавить menuitem 'Close' в строку меню, в своем обработчике событий, добавить OleContainer1.DestroyObject, чтобы вы могли прекратить редактирование
  • Запустите это приложение, дважды щелкните на OleContainer, чтобы он перешел в editmode
  • Теперь откройте Word 2000
  • Вернитесь к своему приложению, контекстное меню больше не будет работать.

Изменить: Я воспроизвел выше поведение в следующей системе (используя Citrix):

Windows Server 2003 Enterprise Edition
Версия 5.2 (сборка 3790.srv03_sp2_rtm.070216-1710: пакет обновления 2)

Microsoft Word 2000 (9.0.6926 SP-3)

Я использовал Delphi 7 (сборка 8.1) для создания приложения.

4b9b3361

Ответ 1

При размещении приложений Office через ActiveX вы обнаружите, что некоторые версии некоторых приложений Office смехотворно трогательны в отношении информирования об изменениях активации окна, и это может особенно отразиться на их контекстных меню.

В принципе, если вы не говорите им, когда они теряют или получают фокус, а также каждый раз, когда ваше окно верхнего уровня получает или теряет фокус (даже если их дочерний элемент управления в окне не набирает фокус), тогда они могут пойдите haywire.

Это то, с чем я боролся долгое время и особенно разочаровываю, когда вам приходится рассказывать приложениям, что они находятся в лучшем положении, чтобы знать, чем вы (например, когда они теряют или получают фокус напрямую... или когда они создают всплывающее меню, которое отвлекает внимание от них, и его нужно обрабатывать по-разному с каким-либо другим окном/окном, которое фокусируется, и вы остаетесь божественным... Ugh.

В любом случае приложения Office должны открывать интерфейс IOleInPlaceActiveObject, и вы должны убедиться, что вы вызываете его метод OnFrameWindowActivate, чтобы сообщить об активации/деактивации.

Из памяти и быстрый взгляд на мой собственный код для размещения Office - это одна из самых важных вещей. Также легко забыть, думая: "Нет, это не может быть так важно... Почему бы ничего не волновать, активно ли окно или нет?" Вы можете подумать, что это может привести только к некоторым незначительным косметическим проблемам (например, появляться активным, когда это не так), но это может привести к тому, что все это закроется или сгорит. Поверьте мне, Office заботится слишком много о таких вещах! У меня создалось впечатление, что под обложками Office по-прежнему существует очень старая однопоточная конструкция со времен совместной работы многозадачности, и она может очень запутаться, когда сразу два из них выглядят активными.

Извините, что я не могу дать больше советов, чем просто указывать в этом направлении... Написание хостов ActiveX - это черное искусство (вся документация предназначена для размещения, а не для хоста:() и единственный способ, которым я получил свой собственный код для работы был через месяцы проб и ошибок и чертовски много отладки. К сожалению, это кошмар.

Один из последних советов: не бойтесь жестких кодировок для конкретных приложений. Это то, что делает сам IE, с настройками реестра для контроля того, какие клыджи применяются к тому, что (и я подозреваю, что в код больше жестко закодировано). ActiveX - это такой плохо определенный беспорядок, что различные элементы управления имеют свои собственные причуды и ошибки, и невозможно написать чистый, общий хост, который работает со всеми из них. (Изменение, которое исправляет одно, приведет к поломке другого.) Вы также найдете то, что работает, только если вы пытаетесь использовать интерфейсы в том же порядке, что и IE, только потому, что они были протестированы только с IE; делайте что-то по-другому, и они разваливаются.: (

Ответ 2

Интересно, можете ли вы поймать какое-либо событие типа Lost Focus из формы, содержащей контейнер OLE, и в это время вы могли бы уничтожить документ в контейнере OLE, но сохранить его в памяти. Затем в любом событии типа Got Focus для формы вы можете проверить, есть ли у вас этот документ; если это так, перегрузите его в контейнер OLE.

Будет ли это работать для вас?

Ответ 3

Возможно, вы можете использовать компонент для вызова приложения. У меня никогда не возникало проблемы с созданием настраиваемого компонента для вызова текстовых интерфейсов, а затем регистрации специальных команд в меню. В контейнере вы не можете создать специальное меню в форме? Существует несколько WordSink Evenets, которые помогут в сохранении и закрытии, которые могут использоваться в сочетании со объектами word com.