1340233 protect Dispatch constructor
1185167 Connect to running instance -- experimental API
This commit is contained in:
@@ -84,6 +84,11 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_QueryInterface
|
|||||||
return newAuto;
|
return newAuto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* starts up a new instance of the requested program (progId)
|
||||||
|
* and connects to it. does special code if the progid
|
||||||
|
* is of the alternate format (with ":")
|
||||||
|
**/
|
||||||
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstance
|
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstance
|
||||||
(JNIEnv *env, jobject _this, jstring _progid)
|
(JNIEnv *env, jobject _this, jstring _progid)
|
||||||
{
|
{
|
||||||
@@ -146,6 +151,92 @@ doDisp:
|
|||||||
env->SetIntField(_this, jf, (unsigned int)pIDispatch);
|
env->SetIntField(_this, jf, (unsigned int)pIDispatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* attempts to connect to an running instance of the requested program
|
||||||
|
* This exists solely for the factory method connectToActiveInstance.
|
||||||
|
**/
|
||||||
|
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_getActiveInstance
|
||||||
|
(JNIEnv *env, jobject _this, jstring _progid)
|
||||||
|
{
|
||||||
|
jclass clazz = env->GetObjectClass(_this);
|
||||||
|
jfieldID jf = env->GetFieldID( clazz, DISP_FLD, "I");
|
||||||
|
|
||||||
|
const char *progid = env->GetStringUTFChars(_progid, NULL);
|
||||||
|
CLSID clsid;
|
||||||
|
HRESULT hr;
|
||||||
|
IUnknown *punk = NULL;
|
||||||
|
IDispatch *pIDispatch;
|
||||||
|
USES_CONVERSION;
|
||||||
|
LPOLESTR bsProgId = A2W(progid);
|
||||||
|
env->ReleaseStringUTFChars(_progid, progid);
|
||||||
|
// Now, try to find an IDispatch interface for progid
|
||||||
|
hr = CLSIDFromProgID(bsProgId, &clsid);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
ThrowComFail(env, "Can't get object clsid from progid", hr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// standard connection
|
||||||
|
//printf("trying to connect to running %ls\n",bsProgId);
|
||||||
|
hr = GetActiveObject(clsid,NULL, &punk);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
ThrowComFail(env, "Can't get active object", hr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// now get an IDispatch pointer from the IUnknown
|
||||||
|
hr = punk->QueryInterface(IID_IDispatch, (void **)&pIDispatch);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
ThrowComFail(env, "Can't QI object for IDispatch", hr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// GetActiveObject called AddRef
|
||||||
|
punk->Release();
|
||||||
|
env->SetIntField(_this, jf, (unsigned int)pIDispatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* starts up a new instance of the requested program (progId).
|
||||||
|
* This exists solely for the factory method connectToActiveInstance.
|
||||||
|
**/
|
||||||
|
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_coCreateInstance
|
||||||
|
(JNIEnv *env, jobject _this, jstring _progid)
|
||||||
|
{
|
||||||
|
jclass clazz = env->GetObjectClass(_this);
|
||||||
|
jfieldID jf = env->GetFieldID( clazz, DISP_FLD, "I");
|
||||||
|
|
||||||
|
const char *progid = env->GetStringUTFChars(_progid, NULL);
|
||||||
|
CLSID clsid;
|
||||||
|
HRESULT hr;
|
||||||
|
IUnknown *punk = NULL;
|
||||||
|
IDispatch *pIDispatch;
|
||||||
|
USES_CONVERSION;
|
||||||
|
LPOLESTR bsProgId = A2W(progid);
|
||||||
|
env->ReleaseStringUTFChars(_progid, progid);
|
||||||
|
// Now, try to find an IDispatch interface for progid
|
||||||
|
hr = CLSIDFromProgID(bsProgId, &clsid);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
ThrowComFail(env, "Can't get object clsid from progid", hr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// standard creation
|
||||||
|
hr = CoCreateInstance(clsid,NULL,CLSCTX_LOCAL_SERVER|CLSCTX_INPROC_SERVER,IID_IUnknown, (void **)&punk);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
ThrowComFail(env, "Can't co-create object", hr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// now get an IDispatch pointer from the IUnknown
|
||||||
|
hr = punk->QueryInterface(IID_IDispatch, (void **)&pIDispatch);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
ThrowComFail(env, "Can't QI object for IDispatch", hr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// CoCreateInstance called AddRef
|
||||||
|
punk->Release();
|
||||||
|
env->SetIntField(_this, jf, (unsigned int)pIDispatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* release method
|
||||||
|
*/
|
||||||
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_release
|
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_release
|
||||||
(JNIEnv *env, jobject _this)
|
(JNIEnv *env, jobject _this)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,6 +41,22 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_QueryInterface
|
|||||||
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstance
|
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstance
|
||||||
(JNIEnv *, jobject, jstring);
|
(JNIEnv *, jobject, jstring);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: Dispatch
|
||||||
|
* Method: getActiveInstance
|
||||||
|
* Signature: (Ljava/lang/String;)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_getActiveInstance
|
||||||
|
(JNIEnv *, jobject, jstring);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: Dispatch
|
||||||
|
* Method: coCreateInstance
|
||||||
|
* Signature: (Ljava/lang/String;)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_coCreateInstance
|
||||||
|
(JNIEnv *, jobject, jstring);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: Dispatch
|
* Class: Dispatch
|
||||||
* Method: release
|
* Method: release
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
package com.jacob.samples.test;
|
|
||||||
|
|
||||||
import com.jacob.com.*;
|
|
||||||
import com.jacob.activeX.*;
|
|
||||||
|
|
||||||
class DispatchTest
|
|
||||||
{
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
ComThread.InitSTA();
|
|
||||||
|
|
||||||
ActiveXComponent xl = new ActiveXComponent("Excel.Application");
|
|
||||||
Dispatch xlo = xl.getObject();
|
|
||||||
try {
|
|
||||||
System.out.println("version="+xl.getProperty("Version"));
|
|
||||||
System.out.println("version="+Dispatch.get(xlo, "Version"));
|
|
||||||
Dispatch.put(xlo, "Visible", new Variant(true));
|
|
||||||
Dispatch workbooks = xl.getProperty("Workbooks").toDispatch();
|
|
||||||
Dispatch workbook = Dispatch.get(workbooks,"Add").toDispatch();
|
|
||||||
Dispatch sheet = Dispatch.get(workbook,"ActiveSheet").toDispatch();
|
|
||||||
Dispatch a1 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
|
|
||||||
new Object[] {"A1"},
|
|
||||||
new int[1]).toDispatch();
|
|
||||||
Dispatch a2 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
|
|
||||||
new Object[] {"A2"},
|
|
||||||
new int[1]).toDispatch();
|
|
||||||
Dispatch.put(a1, "Value", "123.456");
|
|
||||||
Dispatch.put(a2, "Formula", "=A1*2");
|
|
||||||
System.out.println("a1 from excel:"+Dispatch.get(a1, "Value"));
|
|
||||||
System.out.println("a2 from excel:"+Dispatch.get(a2, "Value"));
|
|
||||||
Variant f = new Variant(false);
|
|
||||||
Dispatch.call(workbook, "Close", f);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
xl.invoke("Quit", new Variant[] {});
|
|
||||||
ComThread.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -37,7 +37,8 @@ import com.jacob.com.*;
|
|||||||
* the senese that it is used for creating Dispatch objects
|
* the senese that it is used for creating Dispatch objects
|
||||||
*/
|
*/
|
||||||
public class ActiveXComponent extends Dispatch {
|
public class ActiveXComponent extends Dispatch {
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* Normally used to create a new connection to a microsoft application.
|
* Normally used to create a new connection to a microsoft application.
|
||||||
* The passed in parameter is the name of the program as registred
|
* The passed in parameter is the name of the program as registred
|
||||||
* in the registry. It can also be the object name.
|
* in the registry. It can also be the object name.
|
||||||
@@ -64,6 +65,14 @@ public class ActiveXComponent extends Dispatch {
|
|||||||
super(dispatchToBeWrapped);
|
super(dispatchToBeWrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* only used by the factories
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private ActiveXComponent() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Probably was a cover for something else in the past.
|
* Probably was a cover for something else in the past.
|
||||||
* Should be deprecated.
|
* Should be deprecated.
|
||||||
@@ -73,6 +82,64 @@ public class ActiveXComponent extends Dispatch {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Most code should use the standard ActiveXComponent(String) contructor
|
||||||
|
* and not this factory method. This method exists for applications
|
||||||
|
* that need special behavior.
|
||||||
|
* <B>Experimental in release 1.9.2.</B>
|
||||||
|
* <p>
|
||||||
|
* Factory that returns a Dispatch object wrapped around the result
|
||||||
|
* of a CoCreate() call. This differs from the standard constructor
|
||||||
|
* in that it throws no exceptions and returns null on failure.
|
||||||
|
* <p>
|
||||||
|
* This will fail for any prog id with a ":" in it.
|
||||||
|
*
|
||||||
|
* @param pRequestedProgramId
|
||||||
|
* @return Dispatch pointer to the COM object or null if couldn't create
|
||||||
|
*/
|
||||||
|
public static ActiveXComponent createNewInstance(String pRequestedProgramId){
|
||||||
|
ActiveXComponent mCreatedDispatch = null;
|
||||||
|
try {
|
||||||
|
mCreatedDispatch = new ActiveXComponent();
|
||||||
|
mCreatedDispatch.coCreateInstanceJava(pRequestedProgramId);
|
||||||
|
} catch (Exception e){
|
||||||
|
mCreatedDispatch =null;
|
||||||
|
if (JacobObject.isDebugEnabled()){
|
||||||
|
JacobObject.debug("Unable to co-create instance of "+pRequestedProgramId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mCreatedDispatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Most code should use the standard ActiveXComponent(String) contructor
|
||||||
|
* and not this factory method. This method exists for applications
|
||||||
|
* that need special behavior.
|
||||||
|
* <B>Experimental in release 1.9.2.</B>
|
||||||
|
* <p>
|
||||||
|
* Factory that returns a Dispatch wrapped around the result
|
||||||
|
* of a getActiveObject() call. This differs from the standard constructor
|
||||||
|
* in that it throws no exceptions and returns null on failure.
|
||||||
|
* <p>
|
||||||
|
* This will fail for any prog id with a ":" in it
|
||||||
|
*
|
||||||
|
* @param pRequestedProgramId
|
||||||
|
* @return Dispatch pointer to a COM object or null if wasn't already running
|
||||||
|
*/
|
||||||
|
public static ActiveXComponent connectToActiveInstance(String pRequestedProgramId){
|
||||||
|
ActiveXComponent mCreatedDispatch = null;
|
||||||
|
try {
|
||||||
|
mCreatedDispatch = new ActiveXComponent();
|
||||||
|
mCreatedDispatch.getActiveInstanceJava(pRequestedProgramId);
|
||||||
|
} catch (Exception e){
|
||||||
|
mCreatedDispatch =null;
|
||||||
|
if (JacobObject.isDebugEnabled()){
|
||||||
|
JacobObject.debug("Unable to attach to running instance of "+pRequestedProgramId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mCreatedDispatch;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see com.jacob.com.Dispatch#finalize()
|
* @see com.jacob.com.Dispatch#finalize()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -150,11 +150,18 @@ public class Dispatch extends JacobObject
|
|||||||
* This constructor always creates a new windows/program object
|
* This constructor always creates a new windows/program object
|
||||||
* because it is based on the CoCreate() windows function.
|
* because it is based on the CoCreate() windows function.
|
||||||
* <p>
|
* <p>
|
||||||
|
* Fails silently if null is passed in as the program id
|
||||||
|
* <p>
|
||||||
* @param requestedProgramId
|
* @param requestedProgramId
|
||||||
*/
|
*/
|
||||||
public Dispatch(String requestedProgramId) {
|
public Dispatch(String requestedProgramId) {
|
||||||
programId = requestedProgramId;
|
programId = requestedProgramId;
|
||||||
createInstance(requestedProgramId);
|
if (programId != null && !"".equals(programId)){
|
||||||
|
createInstance(requestedProgramId);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Dispatch(String) does not accept null or an empty string as a parameter");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -163,10 +170,59 @@ public class Dispatch extends JacobObject
|
|||||||
* Windows CoCreate() call
|
* Windows CoCreate() call
|
||||||
* <P>
|
* <P>
|
||||||
* This ends up calling CoCreate down in the JNI layer
|
* This ends up calling CoCreate down in the JNI layer
|
||||||
|
* <p>
|
||||||
|
* The behavior is different if a ":" character exists in the progId. In that
|
||||||
|
* case CoGetObject and CreateInstance (someone needs to describe this better)
|
||||||
*
|
*
|
||||||
* @param progid
|
* @param progid
|
||||||
*/
|
*/
|
||||||
protected native void createInstance(String progid);
|
private native void createInstance(String progid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* native call getActiveInstance only used by the constructor with the same parm
|
||||||
|
* type. This probably should be private. It is the wrapper for the
|
||||||
|
* Windows GetActiveObject() call
|
||||||
|
* <P>
|
||||||
|
* This ends up calling GetActiveObject down in the JNI layer
|
||||||
|
* <p>
|
||||||
|
* This does not have the special behavior for program ids with ":" in them
|
||||||
|
* that createInstance has.
|
||||||
|
*
|
||||||
|
* @param progid
|
||||||
|
*/
|
||||||
|
private native void getActiveInstance(String progid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around the native method
|
||||||
|
* @param progid
|
||||||
|
*/
|
||||||
|
protected void getActiveInstanceJava(String progid){
|
||||||
|
this.programId = progid;
|
||||||
|
getActiveInstance(progid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* native call coCreateInstance only used by the constructor with the same parm
|
||||||
|
* type. This probably should be private. It is the wrapper for the
|
||||||
|
* Windows CoCreate() call
|
||||||
|
* <P>
|
||||||
|
* This ends up calling CoCreate down in the JNI layer
|
||||||
|
* <p>
|
||||||
|
* This does not have the special behavior for program ids with ":" in them
|
||||||
|
* that createInstance has.
|
||||||
|
*
|
||||||
|
* @param progid
|
||||||
|
*/
|
||||||
|
private native void coCreateInstance(String progid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around the native method
|
||||||
|
* @param progid
|
||||||
|
*/
|
||||||
|
protected void coCreateInstanceJava(String progid){
|
||||||
|
this.programId = progid;
|
||||||
|
coCreateInstance(progid);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a different interface by IID string.
|
* Return a different interface by IID string.
|
||||||
|
|||||||
60
unittest/com/jacob/com/ActiveXComponentFactoryTest.java
Normal file
60
unittest/com/jacob/com/ActiveXComponentFactoryTest.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
import com.jacob.activeX.ActiveXComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This exercises the two Dispatch factor methods that let you
|
||||||
|
* control whether you create a new running COM object or connect to an existing one
|
||||||
|
*
|
||||||
|
* -Djava.library.path=d:/jacob/release -Dcom.jacob.autogc=false -Dcom.jacob.debug=true
|
||||||
|
*
|
||||||
|
* @author joe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ActiveXComponentFactoryTest {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
ComThread.InitSTA(true);
|
||||||
|
try {
|
||||||
|
System.out.println("This test only works if MS Word is NOT already running");
|
||||||
|
String mApplicationId = "Word.Application";
|
||||||
|
ActiveXComponent mTryConnectingFirst = ActiveXComponent.connectToActiveInstance(mApplicationId);
|
||||||
|
if (mTryConnectingFirst != null ){
|
||||||
|
mTryConnectingFirst.invoke("Quit",new Variant[] {});
|
||||||
|
System.out.println("Was able to connect to MSWord when hadn't started it");
|
||||||
|
} else {
|
||||||
|
System.out.println("Correctly could not connect to running MSWord");
|
||||||
|
}
|
||||||
|
System.out.println(" Word Starting");
|
||||||
|
ActiveXComponent mTryStartingSecond = ActiveXComponent.createNewInstance(mApplicationId);
|
||||||
|
if (mTryStartingSecond == null){
|
||||||
|
System.out.println("was unable to start up MSWord ");
|
||||||
|
} else {
|
||||||
|
System.out.println("Correctly could start MSWord");
|
||||||
|
}
|
||||||
|
ActiveXComponent mTryConnectingThird = ActiveXComponent.connectToActiveInstance(mApplicationId);
|
||||||
|
if (mTryConnectingThird == null ){
|
||||||
|
System.out.println("was unable able to connect to MSWord after previous startup");
|
||||||
|
} else {
|
||||||
|
System.out.println("Correctly could connect to running MSWord");
|
||||||
|
// stop it so we can fail trying to connect to a running
|
||||||
|
mTryConnectingThird.invoke("Quit",new Variant[] {});
|
||||||
|
System.out.println(" Word stopped");
|
||||||
|
}
|
||||||
|
Thread.sleep(2000);
|
||||||
|
ActiveXComponent mTryConnectingFourth = ActiveXComponent.connectToActiveInstance(mApplicationId);
|
||||||
|
if (mTryConnectingFourth != null ){
|
||||||
|
System.out.println("Was able to connect to MSWord that was stopped");
|
||||||
|
mTryConnectingFourth.invoke("Quit",new Variant[] {});
|
||||||
|
} else {
|
||||||
|
System.out.println("Correctly could not connect to running MSWord");
|
||||||
|
}
|
||||||
|
} catch (ComException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
System.out.println("About to sleep for 2 seconds so we can bask in the glory of this success");
|
||||||
|
Thread.sleep(2000);
|
||||||
|
ComThread.Release();
|
||||||
|
ComThread.quitMainSTA();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
unittest/com/jacob/com/DispatchNullProgramId.java
Normal file
32
unittest/com/jacob/com/DispatchNullProgramId.java
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test verifies that the Dispatch object protects itself when
|
||||||
|
* the constructor is called with a null program id.
|
||||||
|
* Prior to this protection, the VM might crash.m
|
||||||
|
* @author joe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DispatchNullProgramId {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
String nullParam = null;
|
||||||
|
new Dispatch(nullParam);
|
||||||
|
System.out.println(
|
||||||
|
"the dispatch failed to protect itself from null program ids");
|
||||||
|
} catch (IllegalArgumentException iae){
|
||||||
|
System.out.println(
|
||||||
|
"the dispatch protected itself from null program ids");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String nullParam = "";
|
||||||
|
new Dispatch(nullParam);
|
||||||
|
System.out.println(
|
||||||
|
"the dispatch failed to protect itself from empty string program ids");
|
||||||
|
} catch (IllegalArgumentException iae){
|
||||||
|
System.out.println(
|
||||||
|
"the dispatch protected itself from empty string program ids");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
50
unittest/com/jacob/com/ExcelEventTest.java
Normal file
50
unittest/com/jacob/com/ExcelEventTest.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
import com.jacob.activeX.ActiveXComponent;
|
||||||
|
import com.jacob.com.ComFailException;
|
||||||
|
import com.jacob.com.DispatchEvents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test was lifted from a forum posting and shows how you can't listen to
|
||||||
|
* Excel events added post 1.9.1 Eclipse Settings...
|
||||||
|
* -Djava.library.path=d:/jacob/release -Dcom.jacob.autogc=false
|
||||||
|
* -Dcom.jacob.debug=true
|
||||||
|
*/
|
||||||
|
public class ExcelEventTest {
|
||||||
|
|
||||||
|
public static void main(String args[]) {
|
||||||
|
|
||||||
|
listenTo("Word.Application",null);
|
||||||
|
|
||||||
|
// Create an Excel Listener
|
||||||
|
listenTo("Excel.Application",
|
||||||
|
"C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void listenTo(String pid, String typeLibLocation) {
|
||||||
|
|
||||||
|
// Grab The Component.
|
||||||
|
ActiveXComponent axc = new ActiveXComponent(pid);
|
||||||
|
try {
|
||||||
|
// Add a listener (doesn't matter what it is).
|
||||||
|
DispatchEvents de;
|
||||||
|
if (typeLibLocation == null){
|
||||||
|
de = new DispatchEvents(axc, new ExcelEventTest());
|
||||||
|
} else {
|
||||||
|
de = new DispatchEvents(axc, new ExcelEventTest(),
|
||||||
|
pid,typeLibLocation);
|
||||||
|
}
|
||||||
|
if (de == null){
|
||||||
|
System.out.println(
|
||||||
|
"No exception thrown but now dispatch returned for Excel events");
|
||||||
|
}
|
||||||
|
// Yea!
|
||||||
|
System.out.println("Successfully attached to " + pid);
|
||||||
|
} catch (ComFailException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.out.println("Failed to attach to " + pid + ": "
|
||||||
|
+ e.getMessage());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user