我正在编写一个Java程序,它使用Jacob library(桥接COM和Java)与Microsoft Outlook交互。该程序为用户创建了一个新的MailItem,displaying其Inspector窗口。我希望订阅检查员的Close event,以了解用户何时完成了邮件的编辑。
要订阅该活动,我按照Jacob's documentation中的说明(关于页面上的 2 / 3 ):
当前[事件]模型在概念上 类似于Visual Basic
WithEvents
构造。基本上,我提供了一个 上课了com.jacob.com.DispatchEvents
有 一个获取源的构造函数 对象(类型com.jacob.com.Dispatch
)和目标 对象(任何类型)。来源 对象被查询IConnectionPointContainer
界面 我试图获得一个IConnectionPoint
为默认值 源接口(我从中获取)IProvideClassInfo
)。同时, 我还创建了DISPID的映射 对于默认的源接口 实际的方法名称。然后我用 获取jmethodID
的方法名称 来自目标Java对象的句柄。 目前必须拥有所有事件方法 相同的签名:一个论点 是一个变种的Java数组,和 void return type。
这是我的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
According to Google,其他一些人也收到了这个错误。不幸的是,他们都没有得到答案。
我正在使用雅各布库的1.7版,它声称可以防止这个问题:
1.7版还包括要读取的代码 直接来自的类型库 进程id。这使得工作成为可能 与所有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");
所有这些尝试都失败并出现同样的错误。
答案 0 :(得分:2)
经过一些实验,我决定通过订阅MailItem
's Close
event而不是Inspector
's Close
event来达到预期的效果。我现在有一个MailItemEventHandler
类来处理所有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");
}
}
我使用以下方式订阅活动:
Object outlook = new ActiveXComponent("Outlook.Application");
Object mailItem = Dispatch.call(outlook, "CreateItem", 0).getDispatch();
MailItemEventHandler eventHandler = new MailItemEventHandler();
new DispatchEvents((Dispatch) mailItem, eventHandler);
我对COM知之甚少,但看来Inspector
对象注册有问题......
答案 1 :(得分:1)
雅各布可能在你努力完成工作后发生了变化。今天,使用Jacob 1.15-M3,我设法从Excel接收事件,但只使用了4个参数构造函数:
DispatchEvents de = new DispatchEvents(
sh,
new Sink(),
"Excel.Sheet",
"C:\\Program Files (x86)\\Microsoft Office\\OFFICE11\\EXCEL.EXE"
);
给可执行文件的路径是非常不可移植的,但我想有可能以某种方式解决它。我只是在做测试,所以硬编码的可执行文件对我来说还可以。
参数越少,我就会收到与您相同的错误:
Exception in thread "main" com.jacob.com.ComFailException: Can't find event iid
(...)
GetEventIID: couldn't get IProvideClassInfo
答案 2 :(得分:0)
我想附加到Word实例的Close事件,并且如果没有将正确的Dispatch对象放在DispatchEvents的参数列表中,则会出现类似错误,但现在这种情况适用于我的情况。
ActiveXComponent oWord = new ActiveXComponent("Word.Application");
oWord.setProperty("Visible", new Variant(true));
Dispatch oDocuments = oWord.getProperty("Documents").toDispatch();
Dispatch oDocument = Dispatch.call(oDocuments, "Open", strInputDoc).toDispatch();
WordEventHandler w = new WordEventHandler();
new DispatchEvents(oDocument, w);
和
import com.jacob.com.*;
public class WordEventHandler {
public void Close(Variant[] arguments) {
System.out.println("closed word document");
}
}