我正在编写一个 Java 程序,它使用 Jacob 库(桥接 COM 和 Java)与 Microsoft Outlook 交互。此程序创建一个新的 MailItem, 显示其检查器 窗口给用户。我希望订阅检查员的关闭活动 了解用户何时完成编辑邮件项目。
为了订阅该活动,我按照 Jacob 文档 中的说明进行操作(关于 2 ⁄3 下一页):
当前的[事件]模型在概念上是
类似于 Visual Basic WithEvents
构造。基本上,我提供了一个
类称为
com.jacob.com.DispatchEvents
其中有
一个带有源的构造函数
对象(类型
com.jacob.com.Dispatch
)和一个目标
对象(任何类型)。来源
查询对象的
IConnectionPointContainer
接口
我试图获得
IConnectionPoint
为其默认值
源接口(我从
IProvideClassInfo
)。同时,
我还创建了 DISPID 的映射
对于默认源接口
实际的方法名称。然后我用
获取jmethodID
的方法名称
来自目标 Java 对象的句柄。
当前所有事件方法都必须具有
相同的签名:一个参数
是一个 Java Variants 数组,以及
void 返回类型。
这是我的 InspectorEventHandler
类,符合 Jacob 的文档:
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 还包含可读取的代码
直接从类型库
前辈。这使得工作成为可能
与所有 Microsoft Office
应用程序事件,以及 IE5
事件。有关示例,请参阅
示例/测试/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");
所有这些尝试都因相同的错误而失败。
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 called
com.jacob.com.DispatchEvents
which has
a constructor that takes a source
object (of type
com.jacob.com.Dispatch
) and a target
object (of any type). The source
object is queried for its
IConnectionPointContainer
interface
and I attempt to obtain an
IConnectionPoint
for its default
source interface (which I obtain from
IProvideClassInfo
). 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 get jmethodID
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.
发布评论
评论(3)
经过一番实验,我确定通过订阅
MailItem
的Close
事件 而不是检查器
的关闭
事件。我现在有一个MailItemEventHandler
类,可以处理所有MailItem
events:我使用以下方式订阅事件:
我对 COM 不太了解,但
Inspector< 似乎有问题/code> 对象注册...
After some experimentation, I determined that I could achieve the desired result by subscribing to the
MailItem
'sClose
event rather than theInspector
'sClose
event. I now have aMailItemEventHandler
class that handles allMailItem
events:I subscribe to the events using:
I don't know much about COM, but it appears that there is something wrong with the
Inspector
object registration...自从你努力做好你的工作以来,雅各布可能已经改变了。今天,使用 Jacob 1.15-M3,我成功地从 Excel 接收事件,但仅使用 4 个参数构造函数:
给出可执行文件的路径是相当不可移植的,但我想可以通过某种方式解决它。我只是在做测试,所以硬编码的可执行文件对我来说没问题。
由于参数较少,我收到了与您相同的错误:
Jacob may have changed since you were trying to do your job. Today, with Jacob 1.15-M3, I managed to receive events from Excel, but only using 4 argument constructor:
Giving the path to the executable is quite unportable, but I guess it's possible to workaround it somehow. I was only doing tests, so hardcoded executable was ok for me.
With fewer arguments I was receiving the same errors as you:
我想附加到 Word 实例的 Close 事件,如果没有将正确的 Dispatch 对象放入 DispatchEvents 的参数列表中,则会出现类似的错误,但这现在适用于我的情况。
和
I wanted to attach to the Close event of an Word instance and got similar error if didn't put the right Dispatch object in the parameter list of DispatchEvents, but this works in my case, now.
and