Я пишу программу на Java, которая взаимодействует с Microsoft Outlook, используя библиотеку Jacob (соединяет COM и Java). Эта программа создает новый MailItem, отображает его Inspector для пользователя. Я хочу подписаться на событие Close инспектора, чтобы узнать, когда пользователь закончит редактировать свой почтовый элемент.
Чтобы подписаться на мероприятие, я следовал инструкциям в документации Джейкоба (о 2 3 вниз по странице):
Текущая модель [event] концептуально похожа на конструкцию Visual Basic
WithEvents
. По сути, я предоставляю класс с именемcom.jacob.com.DispatchEvents
, у которого есть конструктор, принимающий исходный объект (типаcom.jacob.com.Dispatch
) и целевой объект (любого типа). Исходный объект запрашивается для его интерфейсаIConnectionPointContainer
, и я пытаюсь получитьIConnectionPoint
для его исходного интерфейса по умолчанию (который я получаю отIProvideClassInfo
). В то же время я также создаю сопоставление DISPID для исходного интерфейса по умолчанию с фактическими именами методов. Затем я использую имена методов для полученияjmethodID
дескрипторов целевого объекта Java. Все методы событий в настоящее время должны иметь одинаковую сигнатуру: один аргумент, представляющий собой массив вариантов Java, и тип возвращаемого значения void.
Вот мой класс InspectorEventHandler
, соответствующий документации Джейкоба:
public class InspectorEventHandler {
public void Activate(Variant[] arguments) {
}
public void BeforeMaximize(Variant[] arguments) {
}
public void BeforeMinimize(Variant[] arguments) {
}
public void BeforeMove(Variant[] arguments) {
}
public void BeforeSize(Variant[] arguments) {
}
public void Close(Variant[] arguments) {
System.out.println("Closing");
}
public void Deactivate(Variant[] arguments) {
}
public void PageChange(Variant[] arguments) {
}
}
А вот как я подписываюсь на события, используя этот класс InspectorEventHandler
:
Object outlook = new ActiveXComponent("Outlook.Application");
Object mailItem = Dispatch.call(outlook, "CreateItem", 0).getDispatch();
Object inspector = Dispatch.get(mailItem, "GetInspector").getDispatch();
InspectorEventHandler eventHandler = new InspectorEventHandler();
// This supposedly registers eventHandler with the inspector
new DispatchEvents((Dispatch) inspector, eventHandler);
Однако последняя строка завершается ошибкой со следующим исключением:
Exception in thread "main" com.jacob.com.ComFailException: Can't find event iid at com.jacob.com.DispatchEvents.init(Native Method) at com.jacob.com.DispatchEvents.(DispatchEvents.java) at cake.CakeApplication.run(CakeApplication.java:30) at cake.CakeApplication.main(CakeApplication.java:15) couldn't get IProvideClassInfo
По данным Google, несколько другие также получили эту ошибку. К сожалению, ни один из них не получил ответа.
Я использую библиотеку Jacob версии 1.7, которая, как утверждается, предотвращает эту проблему:
Версия 1.7 также включает код для чтения библиотеки типов непосредственно из файла progid. Это позволяет работать со всеми событиями приложений Microsoft Office, а также с событиями IE5. Пример см. в примере Samples/test/IETest.java.
Я заметил, что вышеупомянутый файл IETest.java
подписывается на такие события:
new DispatchEvents((Dispatch) ieo, ieE,"InternetExplorer.Application.1");
Поэтому я попытался подписаться на свои события аналогичным образом:
new DispatchEvents((Dispatch) inspector, eventHandler, "Outlook.Application");
new DispatchEvents((Dispatch) inspector, eventHandler, "Outlook.Application.1");
new DispatchEvents((Dispatch) inspector, eventHandler, "Outlook.Application.12");
Все эти попытки заканчивались одной и той же ошибкой.