問題描述
我正在編寫一個(gè)使用 Jacob 庫(橋接 COM 和 Java)與 Microsoft Outlook 交互的 Java 程序).該程序創(chuàng)建一個(gè)新的 MailItem,顯示它的Inspector 窗口給用戶.我希望訂閱檢查員的 關(guān)閉事件 知道用戶何時(shí)完成了他們的郵件項(xiàng)目的編輯.
要訂閱該活動,我按照 Jacob 的文檔 中的說明進(jìn)行操作(關(guān)于 2⁄3 在頁面下方):
<塊引用>當(dāng)前的 [event] 模型在概念上是類似于 Visual Basic WithEvents
構(gòu)造.基本上,我提供了一個(gè)類稱為com.jacob.com.DispatchEvents
其中有一個(gè)接受源的構(gòu)造函數(shù)對象(類型com.jacob.com.Dispatch
) 和一個(gè)目標(biāo)對象(任何類型).來源查詢對象的IConnectionPointContainer
接口我試圖獲得一個(gè)IConnectionPoint
為其默認(rèn)值源接口(我從IProvideClassInfo
).同時(shí),我還創(chuàng)建了 DISPID 的映射對于默認(rèn)源接口實(shí)際的方法名稱.然后我用獲取 jmethodID
的方法名稱來自目標(biāo) Java 對象的句柄.目前所有的事件方法都必須有相同的簽名:一個(gè)論點(diǎn)是一個(gè) Java 變體數(shù)組,以及一個(gè)void 返回類型.
這是我的 InspectorEventHandler
類,符合 Jacob 的文檔:
公共類 InspectorEventHandler {公共無效激活(變體[]參數(shù)){}public void BeforeMaximize(Variant[] arguments) {}public void BeforeMinimize(Variant[] arguments) {}public void BeforeMove(Variant[] arguments) {}public void BeforeSize(Variant[] arguments) {}公共無效關(guān)閉(變量[]參數(shù)){System.out.println("關(guān)閉");}公共無效停用(變體[]參數(shù)){}公共無效頁面更改(變體 [] 參數(shù)){}}
下面是我使用這個(gè) InspectorEventHandler
類訂閱事件的方式:
Object outlook = new ActiveXComponent("Outlook.Application");對象 mailItem = Dispatch.call(outlook, "CreateItem", 0).getDispatch();對象檢查器 = Dispatch.get(mailItem, "GetInspector").getDispatch();InspectorEventHandler eventHandler = new InspectorEventHandler();//這應(yīng)該向檢查器注冊 eventHandlernew DispatchEvents((Dispatch) 檢查器,eventHandler);
但是,最后一行失敗并出現(xiàn)以下異常:
<上一頁>線程主"com.jacob.com.ComFailException 中的異常:找不到事件 iid在 com.jacob.com.DispatchEvents.init(本機(jī)方法)在 com.jacob.com.DispatchEvents.(DispatchEvents.java)在 cake.CakeApplication.run(CakeApplication.java:30)在 cake.CakeApplication.main(CakeApplication.java:15)無法獲得 IProvideClassInfo根據(jù)谷歌,其他一些人也收到此錯誤.不幸的是,他們都沒有收到答復(fù).
我正在使用 Jacob 庫的 1.7 版,它聲稱可以防止此問題:
<塊引用>1.7 版還包括閱讀代碼類型庫直接來自天才.這使得工作成為可能與所有 Microsoft Office應(yīng)用程序事件,以及 IE5事件.有關(guān)示例,請參見samples/test/IETest.java 示例.
我注意到前面提到的 IETest.java
文件訂閱了這樣的事件:
new DispatchEvents((Dispatch) ieo, ieE,"InternetExplorer.Application.1");
因此,我嘗試以類似的方式訂閱我的活動:
new DispatchEvents((Dispatch) 檢查器, eventHandler, "Outlook.Application");new DispatchEvents((Dispatch) 檢查器,eventHandler,Outlook.Application.1");new DispatchEvents((Dispatch) 檢查器,eventHandler,Outlook.Application.12");
所有這些嘗試都因相同的錯誤而失敗.
經(jīng)過一些實(shí)驗(yàn),我確定我可以通過訂閱 MailItem
的 Close
事件 而不是 Inspector
的關(guān)閉
事件.我現(xiàn)在有一個(gè)處理所有 MailItemEventHandler 類"nofollow noreferrer">MailItem
事件:
公共類 MailItemEventHandler {公共無效附件添加(變體[]參數(shù)){System.out.println("附件添加");}公共無效附件讀取(變量[]參數(shù)){System.out.println("附件讀取");}公共無效附件刪除(變量[]參數(shù)){System.out.println("附件刪除");}public void BeforeAttachmentAdd(Variant[] arguments) {System.out.println("BeforeAttachmentAdd");}public void BeforeAttachmentPreview(Variant[] arguments) {System.out.println("BeforeAttachmentPreview");}public void BeforeAttachmentRead(Variant[] arguments) {System.out.println("BeforeAttachmentRead");}public void BeforeAttachmentSave(Variant[] arguments) {System.out.println("BeforeAttachmentSave");}public void BeforeAttachmentWriteToTempFile(Variant[] arguments) {System.out.println("BeforeAttachmentWriteToTempFile");}public void BeforeAutoSave(Variant[] arguments) {System.out.println("自動保存前");}public void BeforeCheckNames(Variant[] arguments) {System.out.println("BeforeCheckNames");}public void BeforeDelete(Variant[] arguments) {System.out.println("刪除前");}公共無效關(guān)閉(變量[]參數(shù)){System.out.println("關(guān)閉");}公共無效CustomAction(變體[]參數(shù)){System.out.println("CustomAction");}公共無效CustomPropertyChange(變量[]參數(shù)){System.out.println("CustomPropertyChange");}公共無效轉(zhuǎn)發(fā)(變體[]參數(shù)){System.out.println("轉(zhuǎn)發(fā)");}公共無效開放(變體[]參數(shù)){System.out.println("打開");}公共無效PropertyChange(變體[]參數(shù)){System.out.println("PropertyChange");}公共無效讀取(變量[]參數(shù)){System.out.println("讀取");}公共無效回復(fù)(變體[]參數(shù)){System.out.println("回復(fù)");}公共無效回復(fù)所有(變體[]參數(shù)){System.out.println("ReplyAll");}公共無效發(fā)送(變體[]參數(shù)){System.out.println("發(fā)送");}公共無效卸載(變體[]參數(shù)){System.out.println("卸載");}公共無效寫入(變體 [] 參數(shù)){System.out.println("寫");}}
我使用以下方式訂閱事件:
Object outlook = new ActiveXComponent("Outlook.Application");對象 mailItem = Dispatch.call(outlook, "CreateItem", 0).getDispatch();MailItemEventHandler eventHandler = new MailItemEventHandler();新的 DispatchEvents((Dispatch) mailItem, eventHandler);
我對COM了解不多,但是看來Inspector
對象注冊有問題...
I am writing a Java program that interacts with Microsoft Outlook using the Jacob library (bridges COM and Java). This program creates a new MailItem, displaying its Inspector window to the user. I wish to subscribe to the inspector's Close event to know when the user is finished editing their mail item.
To subscribe to the event, I followed the instructions in Jacob's documentation (about 2⁄3 down the page):
The current [event] model is conceptually similar to the Visual Basic
WithEvents
construct. Basically, I provide a class calledcom.jacob.com.DispatchEvents
which has a constructor that takes a source object (of typecom.jacob.com.Dispatch
) and a target object (of any type). The source object is queried for itsIConnectionPointContainer
interface and I attempt to obtain anIConnectionPoint
for its default source interface (which I obtain fromIProvideClassInfo
). At the same time, I also create a mapping of DISPID's for the default source interface to the actual method names. I then use the method names to getjmethodID
handles from the target Java object. All event methods currently must have the same signature: one argument which is a Java array of Variants, and a void return type.
Here is my InspectorEventHandler
class, conforming to Jacob's documentation:
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) {
}
}
And here is how I subscribe to the events using this InspectorEventHandler
class:
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);
However, the last line fails with the following exception:
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
According to Google, a few others have also received this error. Unfortunately, none of them have received an answer.
I am using version 1.7 of the Jacob library, which claims to prevent this problem:
Version 1.7 also includes code to read the type library directly from the progid. This makes it possible to work with all the Microsoft Office application events, as well as IE5 events. For an example see the samples/test/IETest.java example.
I noticed that the aforementioned IETest.java
file subscribes to events like this:
new DispatchEvents((Dispatch) ieo, ieE,"InternetExplorer.Application.1");
Therefore, I tried subscribing to my events in a similar manner:
new DispatchEvents((Dispatch) inspector, eventHandler, "Outlook.Application");
new DispatchEvents((Dispatch) inspector, eventHandler, "Outlook.Application.1");
new DispatchEvents((Dispatch) inspector, eventHandler, "Outlook.Application.12");
All these attempts failed with the same error.
After some experimentation, I determined that I could achieve the desired result by subscribing to the MailItem
's Close
event rather than the Inspector
's Close
event. I now have a MailItemEventHandler
class that handles all MailItem
events:
public class MailItemEventHandler {
public void AttachmentAdd(Variant[] arguments) {
System.out.println("AttachmentAdd");
}
public void AttachmentRead(Variant[] arguments) {
System.out.println("AttachmentRead");
}
public void AttachmentRemove(Variant[] arguments) {
System.out.println("AttachmentRemove");
}
public void BeforeAttachmentAdd(Variant[] arguments) {
System.out.println("BeforeAttachmentAdd");
}
public void BeforeAttachmentPreview(Variant[] arguments) {
System.out.println("BeforeAttachmentPreview");
}
public void BeforeAttachmentRead(Variant[] arguments) {
System.out.println("BeforeAttachmentRead");
}
public void BeforeAttachmentSave(Variant[] arguments) {
System.out.println("BeforeAttachmentSave");
}
public void BeforeAttachmentWriteToTempFile(Variant[] arguments) {
System.out.println("BeforeAttachmentWriteToTempFile");
}
public void BeforeAutoSave(Variant[] arguments) {
System.out.println("BeforeAutoSave");
}
public void BeforeCheckNames(Variant[] arguments) {
System.out.println("BeforeCheckNames");
}
public void BeforeDelete(Variant[] arguments) {
System.out.println("BeforeDelete");
}
public void Close(Variant[] arguments) {
System.out.println("Close");
}
public void CustomAction(Variant[] arguments) {
System.out.println("CustomAction");
}
public void CustomPropertyChange(Variant[] arguments) {
System.out.println("CustomPropertyChange");
}
public void Forward(Variant[] arguments) {
System.out.println("Forward");
}
public void Open(Variant[] arguments) {
System.out.println("Open");
}
public void PropertyChange(Variant[] arguments) {
System.out.println("PropertyChange");
}
public void Read(Variant[] arguments) {
System.out.println("Read");
}
public void Reply(Variant[] arguments) {
System.out.println("Reply");
}
public void ReplyAll(Variant[] arguments) {
System.out.println("ReplyAll");
}
public void Send(Variant[] arguments) {
System.out.println("Send");
}
public void Unload(Variant[] arguments) {
System.out.println("Unload");
}
public void Write(Variant[] arguments) {
System.out.println("Write");
}
}
I subscribe to the events using:
Object outlook = new ActiveXComponent("Outlook.Application");
Object mailItem = Dispatch.call(outlook, "CreateItem", 0).getDispatch();
MailItemEventHandler eventHandler = new MailItemEventHandler();
new DispatchEvents((Dispatch) mailItem, eventHandler);
I don't know much about COM, but it appears that there is something wrong with the Inspector
object registration...
這篇關(guān)于Java、Jacob 和 Microsoft Outlook 事件:接收“無法找到事件 iid";錯誤的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!