This commit is contained in:
@@ -7,5 +7,6 @@
|
|||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="lib" path="lib/jxinput.jar"/>
|
<classpathentry kind="lib" path="lib/jxinput.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/jacob-1.15-M3.jar"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|||||||
141
java/src/com/jacob/com/ComException.java
Normal file
141
java/src/com/jacob/com/ComException.java
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard exception thrown by com jni code when there is a problem
|
||||||
|
*/
|
||||||
|
public abstract class ComException extends JacobException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* COM code initializes this filed with an appropriate return code that was
|
||||||
|
* returned by the underlying com code
|
||||||
|
*/
|
||||||
|
protected int hr;
|
||||||
|
/**
|
||||||
|
* No documentation is available at this time. Someone should document this
|
||||||
|
* field
|
||||||
|
*/
|
||||||
|
protected int m_helpContext;
|
||||||
|
/**
|
||||||
|
* No documentation is available at this time. Someone should document this
|
||||||
|
* field
|
||||||
|
*/
|
||||||
|
protected String m_helpFile;
|
||||||
|
/**
|
||||||
|
* No documentation is available at this time. Someone should document this
|
||||||
|
* field
|
||||||
|
*/
|
||||||
|
protected String m_source;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public ComException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor with error code?
|
||||||
|
*
|
||||||
|
* @param newHr ??
|
||||||
|
*/
|
||||||
|
public ComException(int newHr) {
|
||||||
|
super();
|
||||||
|
this.hr = newHr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param newHr
|
||||||
|
* @param description
|
||||||
|
*/
|
||||||
|
public ComException(int newHr, String description) {
|
||||||
|
super(description);
|
||||||
|
this.hr = newHr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param newHr
|
||||||
|
* @param source
|
||||||
|
* @param helpFile
|
||||||
|
* @param helpContext
|
||||||
|
*/
|
||||||
|
public ComException(int newHr, String source, String helpFile,
|
||||||
|
int helpContext) {
|
||||||
|
super();
|
||||||
|
this.hr = newHr;
|
||||||
|
m_source = source;
|
||||||
|
m_helpFile = helpFile;
|
||||||
|
m_helpContext = helpContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param newHr
|
||||||
|
* @param description
|
||||||
|
* @param source
|
||||||
|
* @param helpFile
|
||||||
|
* @param helpContext
|
||||||
|
*/
|
||||||
|
public ComException(int newHr, String description, String source,
|
||||||
|
String helpFile, int helpContext) {
|
||||||
|
super(description);
|
||||||
|
this.hr = newHr;
|
||||||
|
m_source = source;
|
||||||
|
m_helpFile = helpFile;
|
||||||
|
m_helpContext = helpContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param description
|
||||||
|
*/
|
||||||
|
public ComException(String description) {
|
||||||
|
super(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int representation of the help context
|
||||||
|
*/
|
||||||
|
// Methods
|
||||||
|
public int getHelpContext() {
|
||||||
|
return m_helpContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return String ??? help file
|
||||||
|
*/
|
||||||
|
public String getHelpFile() {
|
||||||
|
return m_helpFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int hr result ??
|
||||||
|
*/
|
||||||
|
public int getHResult() {
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return String source ??
|
||||||
|
*/
|
||||||
|
public String getSource() {
|
||||||
|
return m_source;
|
||||||
|
}
|
||||||
|
}
|
||||||
88
java/src/com/jacob/com/ComFailException.java
Normal file
88
java/src/com/jacob/com/ComFailException.java
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* COM Fail Exception class raised when there is a problem
|
||||||
|
*/
|
||||||
|
public class ComFailException extends ComException {
|
||||||
|
/**
|
||||||
|
* eclipse generated to get rid of a wanring
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -266047261992987700L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param hrNew
|
||||||
|
*/
|
||||||
|
public ComFailException(int hrNew) {
|
||||||
|
super(hrNew);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param hrNew
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public ComFailException(int hrNew, String message) {
|
||||||
|
super(hrNew, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param hrNew
|
||||||
|
* @param source
|
||||||
|
* @param helpFile
|
||||||
|
* @param helpContext
|
||||||
|
*/
|
||||||
|
public ComFailException(int hrNew, String source, String helpFile,
|
||||||
|
int helpContext) {
|
||||||
|
super(hrNew, source, helpFile, helpContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param hrNew
|
||||||
|
* @param description
|
||||||
|
* @param source
|
||||||
|
* @param helpFile
|
||||||
|
* @param helpContext
|
||||||
|
*/
|
||||||
|
public ComFailException(int hrNew, String description, String source,
|
||||||
|
String helpFile, int helpContext) {
|
||||||
|
super(hrNew, description, source, helpFile, helpContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No argument Constructor
|
||||||
|
*/
|
||||||
|
public ComFailException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public ComFailException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
169
java/src/com/jacob/com/ComThread.java
Normal file
169
java/src/com/jacob/com/ComThread.java
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a COM level thread This is an abstract class because all the
|
||||||
|
* methods are static and no instances are ever created.
|
||||||
|
*/
|
||||||
|
public abstract class ComThread {
|
||||||
|
private static final int MTA = 0x0;
|
||||||
|
|
||||||
|
private static final int STA = 0x2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comment for <code>haveSTA</code>
|
||||||
|
*/
|
||||||
|
public static boolean haveSTA = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comment for <code>mainSTA</code>
|
||||||
|
*/
|
||||||
|
public static MainSTA mainSTA = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the current java thread to be part of the Multi-threaded COM
|
||||||
|
* Apartment
|
||||||
|
*/
|
||||||
|
public static synchronized void InitMTA() {
|
||||||
|
InitMTA(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the current java thread to be an STA
|
||||||
|
*/
|
||||||
|
public static synchronized void InitSTA() {
|
||||||
|
InitSTA(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the current java thread to be part of the Multi-threaded COM
|
||||||
|
* Apartment, if createMainSTA is true, create a separate MainSTA thread
|
||||||
|
* that will house all Apartment Threaded components
|
||||||
|
*
|
||||||
|
* @param createMainSTA
|
||||||
|
*/
|
||||||
|
public static synchronized void InitMTA(boolean createMainSTA) {
|
||||||
|
Init(createMainSTA, MTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the current java thread to be an STA COM Apartment, if
|
||||||
|
* createMainSTA is true, create a separate MainSTA thread that will house
|
||||||
|
* all Apartment Threaded components
|
||||||
|
*
|
||||||
|
* @param createMainSTA
|
||||||
|
*/
|
||||||
|
public static synchronized void InitSTA(boolean createMainSTA) {
|
||||||
|
Init(createMainSTA, STA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static synchronized void startMainSTA() {
|
||||||
|
mainSTA = new MainSTA();
|
||||||
|
haveSTA = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static synchronized void quitMainSTA() {
|
||||||
|
if (mainSTA != null)
|
||||||
|
mainSTA.quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the current java thread to be part of the MTA/STA COM
|
||||||
|
* Apartment
|
||||||
|
*
|
||||||
|
* @param createMainSTA
|
||||||
|
* @param mode
|
||||||
|
*/
|
||||||
|
public static synchronized void Init(boolean createMainSTA, int mode) {
|
||||||
|
if (createMainSTA && !haveSTA) {
|
||||||
|
// if the current thread is going to be in the MTA and there
|
||||||
|
// is no STA thread yet, then create a main STA thread
|
||||||
|
// to avoid COM creating its own
|
||||||
|
startMainSTA();
|
||||||
|
}
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ComThread: before Init: " + mode);
|
||||||
|
}
|
||||||
|
doCoInitialize(mode);
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ComThread: after Init: " + mode);
|
||||||
|
}
|
||||||
|
ROT.addThread();
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ComThread: after ROT.addThread: " + mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call CoUninitialize to release this java thread from COM
|
||||||
|
*/
|
||||||
|
public static synchronized void Release() {
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ComThread: before clearObjects");
|
||||||
|
}
|
||||||
|
ROT.clearObjects();
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ComThread: before UnInit");
|
||||||
|
}
|
||||||
|
doCoUninitialize();
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ComThread: after UnInit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated the java model leave the responsibility of clearing up
|
||||||
|
* objects to the Garbage Collector. Our programming model
|
||||||
|
* should not require that the user specifically remove object
|
||||||
|
* from the thread.
|
||||||
|
*
|
||||||
|
* This will remove an object from the ROT
|
||||||
|
* @param o
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static synchronized void RemoveObject(JacobObject o) {
|
||||||
|
ROT.removeObject(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param threadModel
|
||||||
|
*/
|
||||||
|
public static native void doCoInitialize(int threadModel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static native void doCoUninitialize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load the Jacob DLL. We do this in case COMThread is called before any
|
||||||
|
* other reference to one of the JacboObject subclasses is made.
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
LibraryLoader.loadJacobLibrary();
|
||||||
|
}
|
||||||
|
}
|
||||||
91
java/src/com/jacob/com/Currency.java
Normal file
91
java/src/com/jacob/com/Currency.java
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Most COM bridges use java.lang.Long as their Java data type for COM Currency
|
||||||
|
* data. This is because COM currency is a 64 bit number where the last 4 digits
|
||||||
|
* represent the milli-cents. We wanted to support 64 bit Long values for x64
|
||||||
|
* platforms so that meant we wanted to map Java.LONG to COM.LONG even though it
|
||||||
|
* only works for 64 bit platforms. The end result was we needed a new
|
||||||
|
* representation for Money so we have this.
|
||||||
|
* <p>
|
||||||
|
* In the future, this should convert to and from BigDecimal or Double
|
||||||
|
*/
|
||||||
|
public class Currency {
|
||||||
|
Long embeddedValue = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor that takes a long already in COM representation
|
||||||
|
*
|
||||||
|
* @param newValue
|
||||||
|
*/
|
||||||
|
public Currency(long newValue) {
|
||||||
|
embeddedValue = new Long(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor that takes a String already in COM representation
|
||||||
|
*
|
||||||
|
* @param newValue
|
||||||
|
*/
|
||||||
|
public Currency(String newValue) {
|
||||||
|
embeddedValue = new Long(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return the currency as a primitive long
|
||||||
|
*/
|
||||||
|
public long longValue() {
|
||||||
|
return embeddedValue.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter to the inner storage so that cmpareTo can work
|
||||||
|
*
|
||||||
|
* @return the embedded long value
|
||||||
|
*/
|
||||||
|
protected Long getLongValue() {
|
||||||
|
return embeddedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* compares the values of two currencies
|
||||||
|
*
|
||||||
|
* @param anotherCurrency
|
||||||
|
* @return the usual compareTo results
|
||||||
|
*/
|
||||||
|
public int compareTo(Currency anotherCurrency) {
|
||||||
|
return embeddedValue.compareTo(anotherCurrency.getLongValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* standard comparison
|
||||||
|
*
|
||||||
|
* @param o
|
||||||
|
* must be Currency or Long
|
||||||
|
* @return the usual compareTo results
|
||||||
|
*/
|
||||||
|
public int compareTo(Object o) {
|
||||||
|
if (o instanceof Currency) {
|
||||||
|
return compareTo((Currency) o);
|
||||||
|
} else if (o instanceof Long) {
|
||||||
|
return embeddedValue.compareTo((Long) o);
|
||||||
|
} else
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Can only compare to Long and Currency not "
|
||||||
|
+ o.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null) {
|
||||||
|
return false;
|
||||||
|
} else if (compareTo(o) == 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
105
java/src/com/jacob/com/DateUtilities.java
Normal file
105
java/src/com/jacob/com/DateUtilities.java
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* java / windows date conversion utilities
|
||||||
|
*
|
||||||
|
* @author joe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DateUtilities {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* converts a windows time to a Java Date Object
|
||||||
|
*
|
||||||
|
* @param comTime
|
||||||
|
* @return Date object representing the windows time as specified in comTime
|
||||||
|
*/
|
||||||
|
static public Date convertWindowsTimeToDate(double comTime) {
|
||||||
|
return new Date(convertWindowsTimeToMilliseconds(comTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a COM time from functions Date(), Time(), Now() to a Java time
|
||||||
|
* (milliseconds). Visual Basic time values are based to 30.12.1899, Java
|
||||||
|
* time values are based to 1.1.1970 (= 0 milliseconds). The difference is
|
||||||
|
* added to the Visual Basic value to get the corresponding Java value. The
|
||||||
|
* Visual Basic double value reads: <day count delta since 30.12.1899>.<1
|
||||||
|
* day percentage fraction>, e.g. "38100.6453" means: 38100 days since
|
||||||
|
* 30.12.1899 plus (24 hours * 0.6453). Example usage:
|
||||||
|
* <code>Date javaDate = new Date(toMilliseconds (vbDate));</code>.
|
||||||
|
*
|
||||||
|
* @param comTime
|
||||||
|
* COM time.
|
||||||
|
* @return Java time.
|
||||||
|
*/
|
||||||
|
static public long convertWindowsTimeToMilliseconds(double comTime) {
|
||||||
|
long result = 0;
|
||||||
|
|
||||||
|
// code from jacobgen:
|
||||||
|
comTime = comTime - 25569D;
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
result = Math.round(86400000L * comTime)
|
||||||
|
- cal.get(Calendar.ZONE_OFFSET);
|
||||||
|
cal.setTime(new Date(result));
|
||||||
|
result -= cal.get(Calendar.DST_OFFSET);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}// convertWindowsTimeToMilliseconds()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* converts a java date to a windows time object (is this timezone safe?)
|
||||||
|
*
|
||||||
|
* @param javaDate
|
||||||
|
* the java date to be converted to windows time
|
||||||
|
* @return the double representing the date in a form windows understands
|
||||||
|
*/
|
||||||
|
static public double convertDateToWindowsTime(Date javaDate) {
|
||||||
|
if (javaDate == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"cannot convert null to windows time");
|
||||||
|
}
|
||||||
|
return convertMillisecondsToWindowsTime(javaDate.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a Java time to a COM time.
|
||||||
|
*
|
||||||
|
* @param milliseconds
|
||||||
|
* Java time.
|
||||||
|
* @return COM time.
|
||||||
|
*/
|
||||||
|
static public double convertMillisecondsToWindowsTime(long milliseconds) {
|
||||||
|
double result = 0.0;
|
||||||
|
|
||||||
|
// code from jacobgen:
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTimeInMillis(milliseconds);
|
||||||
|
milliseconds += (cal.get(Calendar.ZONE_OFFSET) + cal
|
||||||
|
.get(Calendar.DST_OFFSET)); // add GMT offset
|
||||||
|
result = (milliseconds / 86400000D) + 25569D;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}// convertMillisecondsToWindowsTime()
|
||||||
|
}
|
||||||
872
java/src/com/jacob/com/Dispatch.java
Normal file
872
java/src/com/jacob/com/Dispatch.java
Normal file
@@ -0,0 +1,872 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project. All rights reserved. Originator: Dan Adler
|
||||||
|
* (http://danadler.com). Get more information about JACOB at
|
||||||
|
* http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU Lesser General Public License as published by the Free Software Foundation; either version
|
||||||
|
* 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||||
|
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with this library;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object represents MS level dispatch object. Each instance of this points at
|
||||||
|
* some data structure on the MS windows side.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* You're going to live here a lot
|
||||||
|
*/
|
||||||
|
public class Dispatch extends JacobObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to set the locale in a call. The user locale is another option
|
||||||
|
*/
|
||||||
|
public static final int LOCALE_SYSTEM_DEFAULT = 2048;
|
||||||
|
/** used by callN() and callSubN() */
|
||||||
|
public static final int Method = 1;
|
||||||
|
/** used by callN() and callSubN() */
|
||||||
|
public static final int Get = 2;
|
||||||
|
/** used by put() */
|
||||||
|
public static final int Put = 4;
|
||||||
|
/** not used, probably intended for putRef() */
|
||||||
|
public static final int PutRef = 8;
|
||||||
|
/**
|
||||||
|
* One of legal values for GetDispId. Not used in this layer and probably
|
||||||
|
* not needed.
|
||||||
|
*/
|
||||||
|
public static final int fdexNameCaseSensitive = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is public because Dispatch.cpp knows its name and accesses it
|
||||||
|
* directly to get the dispatch id. You really can't rename it or make it
|
||||||
|
* private
|
||||||
|
*/
|
||||||
|
public int m_pDispatch;
|
||||||
|
|
||||||
|
/** program Id passed in by ActiveX components in their constructor */
|
||||||
|
private String programId = null;
|
||||||
|
|
||||||
|
private static int NOT_ATTACHED = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dummy empty array used one doesn't have to be created on every invocation
|
||||||
|
*/
|
||||||
|
private final static Object[] NO_OBJECT_ARGS = new Object[0];
|
||||||
|
/**
|
||||||
|
* Dummy empty array used one doesn't have to be created on every invocation
|
||||||
|
*/
|
||||||
|
private final static Variant[] NO_VARIANT_ARGS = new Variant[0];
|
||||||
|
/**
|
||||||
|
* Dummy empty array used one doesn't have to be created on every invocation
|
||||||
|
*/
|
||||||
|
private final static int[] NO_INT_ARGS = new int[0];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zero argument constructor that sets the dispatch pointer to 0 This is the
|
||||||
|
* only way to create a Dispatch without a value in the pointer field.
|
||||||
|
*/
|
||||||
|
public Dispatch() {
|
||||||
|
m_pDispatch = NOT_ATTACHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor calls createInstance with progid. This is the
|
||||||
|
* constructor used by the ActiveXComponent or by programs that don't like
|
||||||
|
* the activeX interface but wish to create new connections to windows
|
||||||
|
* programs.
|
||||||
|
* <p>
|
||||||
|
* This constructor always creates a new windows/program object because it
|
||||||
|
* is based on the CoCreate() windows function.
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* @param requestedProgramId
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if null is passed in as the program id
|
||||||
|
* <p>
|
||||||
|
*/
|
||||||
|
public Dispatch(String requestedProgramId) {
|
||||||
|
programId = requestedProgramId;
|
||||||
|
if (programId != null && !"".equals(programId)) {
|
||||||
|
createInstanceNative(requestedProgramId);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Dispatch(String) does not accept null or an empty string as a parameter");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* native call createInstance 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>
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
private native void createInstanceNative(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 getActiveInstanceNative(String progid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around the native method
|
||||||
|
*
|
||||||
|
* @param pProgramIdentifier
|
||||||
|
* name of the program you wish to connect to
|
||||||
|
*/
|
||||||
|
protected void getActiveInstance(String pProgramIdentifier) {
|
||||||
|
if (pProgramIdentifier == null || "".equals(pProgramIdentifier)) {
|
||||||
|
throw new IllegalArgumentException("program id is required");
|
||||||
|
}
|
||||||
|
this.programId = pProgramIdentifier;
|
||||||
|
getActiveInstanceNative(pProgramIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 coCreateInstanceNative(String progid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around the native method
|
||||||
|
*
|
||||||
|
* @param pProgramIdentifier
|
||||||
|
*/
|
||||||
|
protected void coCreateInstance(String pProgramIdentifier) {
|
||||||
|
if (pProgramIdentifier == null || "".equals(pProgramIdentifier)) {
|
||||||
|
throw new IllegalArgumentException("program id is required");
|
||||||
|
}
|
||||||
|
this.programId = pProgramIdentifier;
|
||||||
|
coCreateInstanceNative(pProgramIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a different interface by IID string.
|
||||||
|
* <p>
|
||||||
|
* Once you have a Dispatch object, you can navigate to the other interfaces
|
||||||
|
* of a COM object by calling QueryInterafce. The argument is an IID string
|
||||||
|
* in the format: "{9BF24410-B2E0-11D4-A695-00104BFF3241}". You typically
|
||||||
|
* get this string from the idl file (it's called uuid in there). Any
|
||||||
|
* interface you try to use must be derived from IDispatch. T The atl
|
||||||
|
* example uses this.
|
||||||
|
* <p>
|
||||||
|
* The Dispatch instance resulting from this query is instanciated in the
|
||||||
|
* JNI code.
|
||||||
|
*
|
||||||
|
* @param iid
|
||||||
|
* @return Dispatch a disptach that matches ??
|
||||||
|
*/
|
||||||
|
public native Dispatch QueryInterface(String iid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor that only gets called from JNI QueryInterface calls JNI code
|
||||||
|
* that looks up the object for the key passed in. The JNI CODE then creates
|
||||||
|
* a new dispatch object using this constructor
|
||||||
|
*
|
||||||
|
* @param pDisp
|
||||||
|
*/
|
||||||
|
protected Dispatch(int pDisp) {
|
||||||
|
m_pDispatch = pDisp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor to be used by subclass that want to swap themselves in for
|
||||||
|
* the default Dispatch class. Usually you will have a class like
|
||||||
|
* WordDocument that is a subclass of Dispatch and it will have a
|
||||||
|
* constructor public WordDocument(Dispatch). That constructor should just
|
||||||
|
* call this constructor as super(Dispatch)
|
||||||
|
*
|
||||||
|
* @param dispatchToBeDisplaced
|
||||||
|
*/
|
||||||
|
public Dispatch(Dispatch dispatchToBeDisplaced) {
|
||||||
|
// TAKE OVER THE IDispatch POINTER
|
||||||
|
this.m_pDispatch = dispatchToBeDisplaced.m_pDispatch;
|
||||||
|
// NULL OUT THE INPUT POINTER
|
||||||
|
dispatchToBeDisplaced.m_pDispatch = NOT_ATTACHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the program id if an activeX component created this otherwise it
|
||||||
|
* returns null. This was added to aid in debugging
|
||||||
|
*
|
||||||
|
* @return the program id an activeX component was created against
|
||||||
|
*/
|
||||||
|
public String getProgramId() {
|
||||||
|
return programId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#finalize()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void finalize() {
|
||||||
|
safeRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.jacob.com.JacobObject#safeRelease()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void safeRelease() {
|
||||||
|
super.safeRelease();
|
||||||
|
if (isAttached()) {
|
||||||
|
release();
|
||||||
|
m_pDispatch = NOT_ATTACHED;
|
||||||
|
} else {
|
||||||
|
// looks like a double release
|
||||||
|
if (isDebugEnabled()) {
|
||||||
|
debug(this.getClass().getName() + ":" + this.hashCode()
|
||||||
|
+ " double release");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return true if there is an underlying windows dispatch object
|
||||||
|
*/
|
||||||
|
protected boolean isAttached() {
|
||||||
|
if (m_pDispatch == NOT_ATTACHED) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param theOneInQuestion
|
||||||
|
* dispatch being tested
|
||||||
|
* @throws IllegalStateException
|
||||||
|
* if this dispatch isn't hooked up
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if null the dispatch under test is null
|
||||||
|
*/
|
||||||
|
private static void throwIfUnattachedDispatch(Dispatch theOneInQuestion) {
|
||||||
|
if (theOneInQuestion == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Can't pass in null Dispatch object");
|
||||||
|
} else if (theOneInQuestion.isAttached()) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Dispatch not hooked to windows memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* now private so only this object can access was: call this to explicitly
|
||||||
|
* release the com object before gc
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private native void release();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* not implemented yet
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param val
|
||||||
|
* @throws com.jacob.com.NotImplementedException
|
||||||
|
*/
|
||||||
|
public static void put_Casesensitive(Dispatch dispatchTarget, String name,
|
||||||
|
Object val) {
|
||||||
|
throw new NotImplementedException("not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================ start of the
|
||||||
|
* invokev section
|
||||||
|
* ===========================================================
|
||||||
|
*/
|
||||||
|
// eliminate _Guid arg
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param dispID
|
||||||
|
* @param lcid
|
||||||
|
* @param wFlags
|
||||||
|
* @param vArg
|
||||||
|
* @param uArgErr
|
||||||
|
*/
|
||||||
|
public static void invokeSubv(Dispatch dispatchTarget, String name,
|
||||||
|
int dispID, int lcid, int wFlags, Variant[] vArg, int[] uArgErr) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invokev(dispatchTarget, name, dispID, lcid, wFlags, vArg, uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param wFlags
|
||||||
|
* @param vArg
|
||||||
|
* @param uArgErr
|
||||||
|
*/
|
||||||
|
public static void invokeSubv(Dispatch dispatchTarget, String name,
|
||||||
|
int wFlags, Variant[] vArg, int[] uArgErr) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invokev(dispatchTarget, name, 0, Dispatch.LOCALE_SYSTEM_DEFAULT,
|
||||||
|
wFlags, vArg, uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispID
|
||||||
|
* @param wFlags
|
||||||
|
* @param vArg
|
||||||
|
* @param uArgErr
|
||||||
|
*/
|
||||||
|
public static void invokeSubv(Dispatch dispatchTarget, int dispID,
|
||||||
|
int wFlags, Variant[] vArg, int[] uArgErr) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invokev(dispatchTarget, null, dispID, Dispatch.LOCALE_SYSTEM_DEFAULT,
|
||||||
|
wFlags, vArg, uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* not implemented yet
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param values
|
||||||
|
* @return never returns anything because
|
||||||
|
* @throws com.jacob.com.NotImplementedException
|
||||||
|
*/
|
||||||
|
public static Variant callN_CaseSensitive(Dispatch dispatchTarget,
|
||||||
|
String name, Object[] values) {
|
||||||
|
throw new NotImplementedException("not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param args
|
||||||
|
* an array of argument objects
|
||||||
|
*/
|
||||||
|
public static void callSubN(Dispatch dispatchTarget, String name,
|
||||||
|
Object... args) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invokeSubv(dispatchTarget, name, Dispatch.Method | Dispatch.Get,
|
||||||
|
VariantUtilities.objectsToVariants(args), new int[args.length]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispID
|
||||||
|
* @param args
|
||||||
|
* an array of argument objects
|
||||||
|
*/
|
||||||
|
public static void callSubN(Dispatch dispatchTarget, int dispID,
|
||||||
|
Object... args) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invokeSubv(dispatchTarget, dispID, Dispatch.Method | Dispatch.Get,
|
||||||
|
VariantUtilities.objectsToVariants(args), new int[args.length]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================ start of the
|
||||||
|
* getIdsOfNames section
|
||||||
|
* ===========================================================
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @return int id for the passed in name
|
||||||
|
*/
|
||||||
|
public static int getIDOfName(Dispatch dispatchTarget, String name) {
|
||||||
|
int ids[] = getIDsOfNames(dispatchTarget,
|
||||||
|
Dispatch.LOCALE_SYSTEM_DEFAULT, new String[] { name });
|
||||||
|
return ids[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param lcid
|
||||||
|
* @param names
|
||||||
|
* @return int[] in id array for passed in names
|
||||||
|
*/
|
||||||
|
// eliminated _Guid argument
|
||||||
|
public static native int[] getIDsOfNames(Dispatch dispatchTarget, int lcid,
|
||||||
|
String[] names);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param names
|
||||||
|
* @return int[] int id array for passed in names
|
||||||
|
*/
|
||||||
|
// eliminated _Guid argument
|
||||||
|
public static int[] getIDsOfNames(Dispatch dispatchTarget, String[] names) {
|
||||||
|
return getIDsOfNames(dispatchTarget, Dispatch.LOCALE_SYSTEM_DEFAULT,
|
||||||
|
names);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================ start of the
|
||||||
|
* invokev section
|
||||||
|
* ===========================================================
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param args
|
||||||
|
* @return Variant returned by call
|
||||||
|
*/
|
||||||
|
public static Variant callN(Dispatch dispatchTarget, String name,
|
||||||
|
Object... args) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return invokev(dispatchTarget, name, Dispatch.Method | Dispatch.Get,
|
||||||
|
VariantUtilities.objectsToVariants(args), new int[args.length]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispID
|
||||||
|
* @param args
|
||||||
|
* @return Variant returned by call
|
||||||
|
*/
|
||||||
|
public static Variant callN(Dispatch dispatchTarget, int dispID,
|
||||||
|
Object... args) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return invokev(dispatchTarget, dispID, Dispatch.Method | Dispatch.Get,
|
||||||
|
VariantUtilities.objectsToVariants(args), new int[args.length]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param dispID
|
||||||
|
* @param lcid
|
||||||
|
* @param wFlags
|
||||||
|
* @param oArg
|
||||||
|
* @param uArgErr
|
||||||
|
* @return Variant returned by invoke
|
||||||
|
*/
|
||||||
|
public static Variant invoke(Dispatch dispatchTarget, String name,
|
||||||
|
int dispID, int lcid, int wFlags, Object[] oArg, int[] uArgErr) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return invokev(dispatchTarget, name, dispID, lcid, wFlags,
|
||||||
|
VariantUtilities.objectsToVariants(oArg), uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param wFlags
|
||||||
|
* @param oArg
|
||||||
|
* @param uArgErr
|
||||||
|
* @return Variant returned by invoke
|
||||||
|
*/
|
||||||
|
public static Variant invoke(Dispatch dispatchTarget, String name,
|
||||||
|
int wFlags, Object[] oArg, int[] uArgErr) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return invokev(dispatchTarget, name, wFlags, VariantUtilities
|
||||||
|
.objectsToVariants(oArg), uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispID
|
||||||
|
* @param wFlags
|
||||||
|
* @param oArg
|
||||||
|
* @param uArgErr
|
||||||
|
* @return Variant returned by invoke
|
||||||
|
*/
|
||||||
|
public static Variant invoke(Dispatch dispatchTarget, int dispID,
|
||||||
|
int wFlags, Object[] oArg, int[] uArgErr) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return invokev(dispatchTarget, dispID, wFlags, VariantUtilities
|
||||||
|
.objectsToVariants(oArg), uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================ start of the
|
||||||
|
* callN section ===========================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @return Variant returned by underlying callN
|
||||||
|
*/
|
||||||
|
public static Variant call(Dispatch dispatchTarget, String name) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return callN(dispatchTarget, name, NO_VARIANT_ARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param attributes
|
||||||
|
* @return Variant returned by underlying callN
|
||||||
|
*/
|
||||||
|
public static Variant call(Dispatch dispatchTarget, String name,
|
||||||
|
Object... attributes) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return callN(dispatchTarget, name, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispid
|
||||||
|
* @return Variant returned by underlying callN
|
||||||
|
*/
|
||||||
|
public static Variant call(Dispatch dispatchTarget, int dispid) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return callN(dispatchTarget, dispid, NO_VARIANT_ARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispid
|
||||||
|
* @param attributes
|
||||||
|
* var arg list of attributes that will be passed to the
|
||||||
|
* underlying function
|
||||||
|
* @return Variant returned by underlying callN
|
||||||
|
*/
|
||||||
|
public static Variant call(Dispatch dispatchTarget, int dispid,
|
||||||
|
Object... attributes) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return callN(dispatchTarget, dispid, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================ start of the
|
||||||
|
* invoke section
|
||||||
|
* ===========================================================
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param val
|
||||||
|
*/
|
||||||
|
public static void put(Dispatch dispatchTarget, String name, Object val) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invoke(dispatchTarget, name, Dispatch.Put, new Object[] { val },
|
||||||
|
new int[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispid
|
||||||
|
* @param val
|
||||||
|
*/
|
||||||
|
public static void put(Dispatch dispatchTarget, int dispid, Object val) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invoke(dispatchTarget, dispid, Dispatch.Put, new Object[] { val },
|
||||||
|
new int[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================ start of the
|
||||||
|
* invokev section
|
||||||
|
* ===========================================================
|
||||||
|
*/
|
||||||
|
// removed _Guid argument
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param dispID
|
||||||
|
* @param lcid
|
||||||
|
* @param wFlags
|
||||||
|
* @param vArg
|
||||||
|
* @param uArgErr
|
||||||
|
* @return Variant returned by underlying invokev
|
||||||
|
*/
|
||||||
|
public static native Variant invokev(Dispatch dispatchTarget, String name,
|
||||||
|
int dispID, int lcid, int wFlags, Variant[] vArg, int[] uArgErr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param wFlags
|
||||||
|
* @param vArg
|
||||||
|
* @param uArgErr
|
||||||
|
* @return Variant returned by underlying invokev
|
||||||
|
*/
|
||||||
|
public static Variant invokev(Dispatch dispatchTarget, String name,
|
||||||
|
int wFlags, Variant[] vArg, int[] uArgErr) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return invokev(dispatchTarget, name, 0, Dispatch.LOCALE_SYSTEM_DEFAULT,
|
||||||
|
wFlags, vArg, uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param wFlags
|
||||||
|
* @param vArg
|
||||||
|
* @param uArgErr
|
||||||
|
* @param wFlagsEx
|
||||||
|
* @return Variant returned by underlying invokev
|
||||||
|
*/
|
||||||
|
public static Variant invokev(Dispatch dispatchTarget, String name,
|
||||||
|
int wFlags, Variant[] vArg, int[] uArgErr, int wFlagsEx) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
// do not implement IDispatchEx for now
|
||||||
|
return invokev(dispatchTarget, name, 0, Dispatch.LOCALE_SYSTEM_DEFAULT,
|
||||||
|
wFlags, vArg, uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispID
|
||||||
|
* @param wFlags
|
||||||
|
* @param vArg
|
||||||
|
* @param uArgErr
|
||||||
|
* @return Variant returned by underlying invokev
|
||||||
|
*/
|
||||||
|
public static Variant invokev(Dispatch dispatchTarget, int dispID,
|
||||||
|
int wFlags, Variant[] vArg, int[] uArgErr) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return invokev(dispatchTarget, null, dispID,
|
||||||
|
Dispatch.LOCALE_SYSTEM_DEFAULT, wFlags, vArg, uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================ start of the
|
||||||
|
* invokeSubv section
|
||||||
|
* ===========================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
// removed _Guid argument
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param dispid
|
||||||
|
* @param lcid
|
||||||
|
* @param wFlags
|
||||||
|
* @param oArg
|
||||||
|
* @param uArgErr
|
||||||
|
*/
|
||||||
|
public static void invokeSub(Dispatch dispatchTarget, String name,
|
||||||
|
int dispid, int lcid, int wFlags, Object[] oArg, int[] uArgErr) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invokeSubv(dispatchTarget, name, dispid, lcid, wFlags, VariantUtilities
|
||||||
|
.objectsToVariants(oArg), uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================ start of the
|
||||||
|
* invokeSub section
|
||||||
|
* ===========================================================
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param wFlags
|
||||||
|
* @param oArg
|
||||||
|
* @param uArgErr
|
||||||
|
*/
|
||||||
|
public static void invokeSub(Dispatch dispatchTarget, String name,
|
||||||
|
int wFlags, Object[] oArg, int[] uArgErr) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invokeSub(dispatchTarget, name, 0, Dispatch.LOCALE_SYSTEM_DEFAULT,
|
||||||
|
wFlags, oArg, uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispid
|
||||||
|
* @param wFlags
|
||||||
|
* @param oArg
|
||||||
|
* @param uArgErr
|
||||||
|
*/
|
||||||
|
public static void invokeSub(Dispatch dispatchTarget, int dispid,
|
||||||
|
int wFlags, Object[] oArg, int[] uArgErr) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invokeSub(dispatchTarget, null, dispid, Dispatch.LOCALE_SYSTEM_DEFAULT,
|
||||||
|
wFlags, oArg, uArgErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================ start of the
|
||||||
|
* callSubN section
|
||||||
|
* ===========================================================
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* makes call to native callSubN
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public static void callSub(Dispatch dispatchTarget, String name) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
callSubN(dispatchTarget, name, NO_OBJECT_ARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* makes call to native callSubN
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param attributes
|
||||||
|
* var args list of attributes to be passed to underlying
|
||||||
|
* functions
|
||||||
|
*/
|
||||||
|
public static void callSub(Dispatch dispatchTarget, String name,
|
||||||
|
Object... attributes) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
callSubN(dispatchTarget, name, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* makes call to native callSubN
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispid
|
||||||
|
*/
|
||||||
|
public static void callSub(Dispatch dispatchTarget, int dispid) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
callSubN(dispatchTarget, dispid, NO_OBJECT_ARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* makes call to native callSubN
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispid
|
||||||
|
* @param attributes
|
||||||
|
* var args list of attributes to be passed to underlying
|
||||||
|
* function
|
||||||
|
*/
|
||||||
|
public static void callSub(Dispatch dispatchTarget, int dispid,
|
||||||
|
Object... attributes) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
callSubN(dispatchTarget, dispid, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================ start of the
|
||||||
|
* invokev section
|
||||||
|
* ===========================================================
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Cover for call to underlying invokev()
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @return Variant returned by the request for retrieval of parameter
|
||||||
|
*/
|
||||||
|
public static Variant get(Dispatch dispatchTarget, String name) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return invokev(dispatchTarget, name, Dispatch.Get, NO_VARIANT_ARGS,
|
||||||
|
NO_INT_ARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cover for call to underlying invokev()
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispid
|
||||||
|
* @return Variant returned by the request for retrieval of parameter
|
||||||
|
*/
|
||||||
|
public static Variant get(Dispatch dispatchTarget, int dispid) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return invokev(dispatchTarget, dispid, Dispatch.Get, NO_VARIANT_ARGS,
|
||||||
|
NO_INT_ARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============================================================ start of the
|
||||||
|
* invoke section
|
||||||
|
* ===========================================================
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* cover for underlying call to invoke
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @param val
|
||||||
|
*/
|
||||||
|
public static void putRef(Dispatch dispatchTarget, String name, Object val) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invoke(dispatchTarget, name, Dispatch.PutRef, new Object[] { val },
|
||||||
|
new int[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cover for underlying call to invoke
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param dispid
|
||||||
|
* @param val
|
||||||
|
*/
|
||||||
|
public static void putRef(Dispatch dispatchTarget, int dispid, Object val) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
invoke(dispatchTarget, dispid, Dispatch.PutRef, new Object[] { val },
|
||||||
|
new int[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* not implemented yet
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @param name
|
||||||
|
* @return Variant never returned
|
||||||
|
* @throws com.jacob.com.NotImplementedException
|
||||||
|
*/
|
||||||
|
public static Variant get_CaseSensitive(Dispatch dispatchTarget, String name) {
|
||||||
|
throw new NotImplementedException("not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cover for native method
|
||||||
|
*
|
||||||
|
* @param disp
|
||||||
|
* @param dispid
|
||||||
|
* @param lcid
|
||||||
|
* @return 0 if the dispatch is still active and 1 if it has exited
|
||||||
|
*/
|
||||||
|
public static native int hasExited(Dispatch disp, int dispid, int lcid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The method is used to poll until it returns 1, indicating that the COM
|
||||||
|
* server in gone.
|
||||||
|
* <p>
|
||||||
|
* Sourceforge feature request 2927058
|
||||||
|
*
|
||||||
|
* @param dispatchTarget
|
||||||
|
* @return 0 if the dispatch is still active and 1 if it has exited
|
||||||
|
*/
|
||||||
|
public static int hasExited(Dispatch dispatchTarget) {
|
||||||
|
throwIfUnattachedDispatch(dispatchTarget);
|
||||||
|
return hasExited(dispatchTarget, 0, LOCALE_SYSTEM_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
219
java/src/com/jacob/com/DispatchEvents.java
Normal file
219
java/src/com/jacob/com/DispatchEvents.java
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class creates the scaffolding for event callbacks. Every instance of tis
|
||||||
|
* acts as a wrapper around some java object that wants callbacks from the
|
||||||
|
* microsoft side. It represents the connection between Java and COM for
|
||||||
|
* callbacks.
|
||||||
|
* <p>
|
||||||
|
* The callback mechanism will take any event that it receives and try and find
|
||||||
|
* a java method with the same name that accepts the Variant... as a parameter.
|
||||||
|
* It will then wrap the call back data in the Variant array and call the java
|
||||||
|
* method of the object that this DispatchEvents object was initialized with.
|
||||||
|
* <p>
|
||||||
|
* Instances of this class are created with "sink object" that will receive the
|
||||||
|
* event messages. The sink object is wrapped in an Invocation handler that
|
||||||
|
* actually receives the messages and then forwards them on to the "sink
|
||||||
|
* object". The constructors recognize when an instance of InvocationProxy is
|
||||||
|
* passed in and do not create a new InvocationProxy as a wrapper. They instead
|
||||||
|
* use the passed in InvocationProxy.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DispatchEvents extends JacobObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pointer to an MS data struct. The COM layer knows the name of this
|
||||||
|
* variable and puts the windows memory pointer here.
|
||||||
|
*/
|
||||||
|
int m_pConnPtProxy = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the wrapper for the event sink. This object is the one that will be sent
|
||||||
|
* a message when an event occurs in the MS layer. Normally, the
|
||||||
|
* InvocationProxy will forward the messages to a wrapped object that it
|
||||||
|
* contains.
|
||||||
|
*/
|
||||||
|
InvocationProxy mInvocationProxy = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the most commonly used constructor.
|
||||||
|
* <p>
|
||||||
|
* Creates the event callback linkage between the the MS program represented
|
||||||
|
* by the Dispatch object and the Java object that will receive the
|
||||||
|
* callback.
|
||||||
|
* <p>
|
||||||
|
* Can be used on any object that implements IProvideClassInfo.
|
||||||
|
*
|
||||||
|
* @param sourceOfEvent
|
||||||
|
* Dispatch object who's MS app will generate callbacks
|
||||||
|
* @param eventSink
|
||||||
|
* Java object that wants to receive the events
|
||||||
|
*/
|
||||||
|
public DispatchEvents(Dispatch sourceOfEvent, Object eventSink) {
|
||||||
|
this(sourceOfEvent, eventSink, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* None of the samples use this constructor.
|
||||||
|
* <p>
|
||||||
|
* Creates the event callback linkage between the the MS program represented
|
||||||
|
* by the Dispatch object and the Java object that will receive the
|
||||||
|
* callback.
|
||||||
|
* <p>
|
||||||
|
* Used when the program doesn't implement IProvideClassInfo. It provides a
|
||||||
|
* way to find the TypeLib in the registry based on the programId. The
|
||||||
|
* TypeLib is looked up in the registry on the path
|
||||||
|
* HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/(CLID drived from
|
||||||
|
* progid)/ProgID/Typelib
|
||||||
|
*
|
||||||
|
* @param sourceOfEvent
|
||||||
|
* Dispatch object who's MS app will generate callbacks
|
||||||
|
* @param eventSink
|
||||||
|
* Java object that wants to receive the events
|
||||||
|
* @param progId
|
||||||
|
* program id in the registry that has a TypeLib subkey. The
|
||||||
|
* progrId is mapped to a CLSID that is they used to look up the
|
||||||
|
* key to the Typelib
|
||||||
|
*/
|
||||||
|
public DispatchEvents(Dispatch sourceOfEvent, Object eventSink,
|
||||||
|
String progId) {
|
||||||
|
this(sourceOfEvent, eventSink, progId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the event callback linkage between the the MS program represented
|
||||||
|
* by the Dispatch object and the Java object that will receive the
|
||||||
|
* callback.
|
||||||
|
* <p>
|
||||||
|
* This method was added because Excel doesn't implement IProvideClassInfo
|
||||||
|
* and the registry entry for Excel.Application doesn't include a typelib
|
||||||
|
* key.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* DispatchEvents de = new DispatchEvents(someDispatch, someEventHAndler,
|
||||||
|
* "Excel.Application",
|
||||||
|
* "C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE");
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param sourceOfEvent
|
||||||
|
* Dispatch object who's MS app will generate callbacks
|
||||||
|
* @param eventSink
|
||||||
|
* Java object that wants to receive the events
|
||||||
|
* @param progId ,
|
||||||
|
* mandatory if the typelib is specified
|
||||||
|
* @param typeLib
|
||||||
|
* The location of the typelib to use
|
||||||
|
*/
|
||||||
|
public DispatchEvents(Dispatch sourceOfEvent, Object eventSink,
|
||||||
|
String progId, String typeLib) {
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
System.out.println("DispatchEvents: Registering " + eventSink
|
||||||
|
+ "for events ");
|
||||||
|
}
|
||||||
|
if (eventSink instanceof InvocationProxy) {
|
||||||
|
mInvocationProxy = (InvocationProxy) eventSink;
|
||||||
|
} else {
|
||||||
|
mInvocationProxy = getInvocationProxy(eventSink);
|
||||||
|
}
|
||||||
|
if (mInvocationProxy != null) {
|
||||||
|
init3(sourceOfEvent, mInvocationProxy, progId, typeLib);
|
||||||
|
} else {
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("Cannot register null event sink for events");
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Cannot register null event sink for events");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an instance of the proxy configured with pTargetObject as its
|
||||||
|
* target
|
||||||
|
*
|
||||||
|
* @param pTargetObject
|
||||||
|
* @return InvocationProxy an instance of the proxy this DispatchEvents will
|
||||||
|
* send to the COM layer
|
||||||
|
*/
|
||||||
|
protected InvocationProxy getInvocationProxy(Object pTargetObject) {
|
||||||
|
InvocationProxy newProxy = new InvocationProxyAllVariants();
|
||||||
|
newProxy.setTarget(pTargetObject);
|
||||||
|
return newProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hooks up a connection point proxy by progId event methods on the sink
|
||||||
|
* object will be called by name with a signature of <name>(Variant[] args)
|
||||||
|
*
|
||||||
|
* You must specify the location of the typeLib.
|
||||||
|
*
|
||||||
|
* @param src
|
||||||
|
* dispatch that is the source of the messages
|
||||||
|
* @param sink
|
||||||
|
* the object that will receive the messages
|
||||||
|
* @param progId
|
||||||
|
* optional program id. most folks don't need this either
|
||||||
|
* @param typeLib
|
||||||
|
* optional parameter for those programs that don't register
|
||||||
|
* their type libs (like Excel)
|
||||||
|
*/
|
||||||
|
private native void init3(Dispatch src, Object sink, String progId,
|
||||||
|
String typeLib);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* now private so only this object can asccess was: call this to explicitly
|
||||||
|
* release the com object before gc
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private native void release();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#finalize()
|
||||||
|
*/
|
||||||
|
protected void finalize() {
|
||||||
|
safeRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.jacob.com.JacobObject#safeRelease()
|
||||||
|
*/
|
||||||
|
public void safeRelease() {
|
||||||
|
if (mInvocationProxy != null) {
|
||||||
|
mInvocationProxy.setTarget(null);
|
||||||
|
}
|
||||||
|
mInvocationProxy = null;
|
||||||
|
super.safeRelease();
|
||||||
|
if (m_pConnPtProxy != 0) {
|
||||||
|
release();
|
||||||
|
m_pConnPtProxy = 0;
|
||||||
|
} else {
|
||||||
|
// looks like a double release
|
||||||
|
if (isDebugEnabled()) {
|
||||||
|
debug("DispatchEvents:" + this.hashCode() + " double release");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
82
java/src/com/jacob/com/DispatchIdentifier.java
Normal file
82
java/src/com/jacob/com/DispatchIdentifier.java
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bunch of DispatchIds that were pulled out of the Dispatch class for version
|
||||||
|
* 1.14.
|
||||||
|
*/
|
||||||
|
public class DispatchIdentifier {
|
||||||
|
|
||||||
|
private DispatchIdentifier() {
|
||||||
|
// This is utility class so there is no constructor.
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int DISPID_UNKNOWN = -1;
|
||||||
|
public static final int DISPID_VALUE = 0;
|
||||||
|
public static final int DISPID_PROPERTYPUT = -3;
|
||||||
|
public static final int DISPID_NEWENUM = -4;
|
||||||
|
public static final int DISPID_EVALUATE = -5;
|
||||||
|
public static final int DISPID_CONSTRUCTOR = -6;
|
||||||
|
public static final int DISPID_DESTRUCTOR = -7;
|
||||||
|
public static final int DISPID_COLLECT = -8;
|
||||||
|
public static final int DISPID_AUTOSIZE = -500;
|
||||||
|
public static final int DISPID_BACKCOLOR = -501;
|
||||||
|
public static final int DISPID_BACKSTYLE = -502;
|
||||||
|
public static final int DISPID_BORDERCOLOR = -503;
|
||||||
|
public static final int DISPID_BORDERSTYLE = -504;
|
||||||
|
public static final int DISPID_BORDERWIDTH = -505;
|
||||||
|
public static final int DISPID_DRAWMODE = -507;
|
||||||
|
public static final int DISPID_DRAWSTYLE = -508;
|
||||||
|
public static final int DISPID_DRAWWIDTH = -509;
|
||||||
|
public static final int DISPID_FILLCOLOR = -510;
|
||||||
|
public static final int DISPID_FILLSTYLE = -511;
|
||||||
|
public static final int DISPID_FONT = -512;
|
||||||
|
public static final int DISPID_FORECOLOR = -513;
|
||||||
|
public static final int DISPID_ENABLED = -514;
|
||||||
|
public static final int DISPID_HWND = -515;
|
||||||
|
public static final int DISPID_TABSTOP = -516;
|
||||||
|
public static final int DISPID_TEXT = -517;
|
||||||
|
public static final int DISPID_CAPTION = -518;
|
||||||
|
public static final int DISPID_BORDERVISIBLE = -519;
|
||||||
|
public static final int DISPID_APPEARANCE = -520;
|
||||||
|
public static final int DISPID_MOUSEPOINTER = -521;
|
||||||
|
public static final int DISPID_MOUSEICON = -522;
|
||||||
|
public static final int DISPID_PICTURE = -523;
|
||||||
|
public static final int DISPID_VALID = -524;
|
||||||
|
public static final int DISPID_READYSTATE = -525;
|
||||||
|
public static final int DISPID_REFRESH = -550;
|
||||||
|
public static final int DISPID_DOCLICK = -551;
|
||||||
|
public static final int DISPID_ABOUTBOX = -552;
|
||||||
|
public static final int DISPID_CLICK = -600;
|
||||||
|
public static final int DISPID_DBLCLICK = -601;
|
||||||
|
public static final int DISPID_KEYDOWN = -602;
|
||||||
|
public static final int DISPID_KEYPRESS = -603;
|
||||||
|
public static final int DISPID_KEYUP = -604;
|
||||||
|
public static final int DISPID_MOUSEDOWN = -605;
|
||||||
|
public static final int DISPID_MOUSEMOVE = -606;
|
||||||
|
public static final int DISPID_MOUSEUP = -607;
|
||||||
|
public static final int DISPID_ERROREVENT = -608;
|
||||||
|
public static final int DISPID_READYSTATECHANGE = -609;
|
||||||
|
public static final int DISPID_AMBIENT_BACKCOLOR = -701;
|
||||||
|
public static final int DISPID_AMBIENT_DISPLAYNAME = -702;
|
||||||
|
public static final int DISPID_AMBIENT_FONT = -703;
|
||||||
|
public static final int DISPID_AMBIENT_FORECOLOR = -704;
|
||||||
|
public static final int DISPID_AMBIENT_LOCALEID = -705;
|
||||||
|
public static final int DISPID_AMBIENT_MESSAGEREFLECT = -706;
|
||||||
|
public static final int DISPID_AMBIENT_SCALEUNITS = -707;
|
||||||
|
public static final int DISPID_AMBIENT_TEXTALIGN = -708;
|
||||||
|
public static final int DISPID_AMBIENT_USERMODE = -709;
|
||||||
|
public static final int DISPID_AMBIENT_UIDEAD = -710;
|
||||||
|
public static final int DISPID_AMBIENT_SHOWGRABHANDLES = -711;
|
||||||
|
public static final int DISPID_AMBIENT_SHOWHATCHING = -712;
|
||||||
|
public static final int DISPID_AMBIENT_DISPLAYASDEFAULT = -713;
|
||||||
|
public static final int DISPID_AMBIENT_SUPPORTSMNEMONICS = -714;
|
||||||
|
public static final int DISPID_AMBIENT_AUTOCLIP = -715;
|
||||||
|
public static final int DISPID_AMBIENT_APPEARANCE = -716;
|
||||||
|
public static final int DISPID_AMBIENT_CODEPAGE = -725;
|
||||||
|
public static final int DISPID_AMBIENT_PALETTE = -726;
|
||||||
|
public static final int DISPID_AMBIENT_CHARSET = -727;
|
||||||
|
public static final int DISPID_AMBIENT_TRANSFERPRIORITY = -728;
|
||||||
|
}
|
||||||
92
java/src/com/jacob/com/DispatchProxy.java
Normal file
92
java/src/com/jacob/com/DispatchProxy.java
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If you need to pass a COM Dispatch object between STA threads, you have to
|
||||||
|
* marshall the interface. This class is used as follows: the STA that creates
|
||||||
|
* the Dispatch object must construct an instance of this class. Another thread
|
||||||
|
* can then call toDispatch() on that instance and get a Dispatch pointer which
|
||||||
|
* has been marshalled. WARNING: You can only call toDispatch() once! If you
|
||||||
|
* need to call it multiple times (or from multiple threads) you need to
|
||||||
|
* construct a separate DispatchProxy instance for each such case!
|
||||||
|
*/
|
||||||
|
public class DispatchProxy extends JacobObject {
|
||||||
|
/**
|
||||||
|
* Comment for <code>m_pStream</code>
|
||||||
|
*/
|
||||||
|
public int m_pStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marshals the passed in dispatch into the stream
|
||||||
|
*
|
||||||
|
* @param localDispatch
|
||||||
|
*/
|
||||||
|
public DispatchProxy(Dispatch localDispatch) {
|
||||||
|
MarshalIntoStream(localDispatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return Dispatch the dispatch retrieved from the stream
|
||||||
|
*/
|
||||||
|
public Dispatch toDispatch() {
|
||||||
|
return MarshalFromStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
private native void MarshalIntoStream(Dispatch d);
|
||||||
|
|
||||||
|
private native Dispatch MarshalFromStream();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* now private so only this object can access was: call this to explicitly
|
||||||
|
* release the com object before gc
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private native void release();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#finalize()
|
||||||
|
*/
|
||||||
|
public void finalize() {
|
||||||
|
safeRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.jacob.com.JacobObject#safeRelease()
|
||||||
|
*/
|
||||||
|
public void safeRelease() {
|
||||||
|
super.safeRelease();
|
||||||
|
if (m_pStream != 0) {
|
||||||
|
release();
|
||||||
|
m_pStream = 0;
|
||||||
|
} else {
|
||||||
|
// looks like a double release
|
||||||
|
if (isDebugEnabled()) {
|
||||||
|
debug(this.getClass().getName() + ":" + this.hashCode()
|
||||||
|
+ " double release");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
156
java/src/com/jacob/com/EnumVariant.java
Normal file
156
java/src/com/jacob/com/EnumVariant.java
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of IEnumVariant based on code submitted by Thomas Hallgren
|
||||||
|
* (mailto:Thomas.Hallgren@eoncompany.com)
|
||||||
|
*/
|
||||||
|
public class EnumVariant extends JacobObject implements
|
||||||
|
java.util.Enumeration<Variant> {
|
||||||
|
private int m_pIEnumVARIANT;
|
||||||
|
|
||||||
|
private final Variant[] m_recBuf = new Variant[1];
|
||||||
|
|
||||||
|
// this only gets called from JNI
|
||||||
|
//
|
||||||
|
protected EnumVariant(int pIEnumVARIANT) {
|
||||||
|
m_pIEnumVARIANT = pIEnumVARIANT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param disp
|
||||||
|
*/
|
||||||
|
public EnumVariant(Dispatch disp) {
|
||||||
|
int[] hres = new int[1];
|
||||||
|
Variant evv = Dispatch.invokev(disp, DispatchIdentifier.DISPID_NEWENUM,
|
||||||
|
Dispatch.Get, new Variant[0], hres);
|
||||||
|
if (evv.getvt() != Variant.VariantObject)
|
||||||
|
//
|
||||||
|
// The DISPID_NEWENUM did not result in a valid object
|
||||||
|
//
|
||||||
|
throw new ComFailException("Can't obtain EnumVARIANT");
|
||||||
|
|
||||||
|
EnumVariant tmp = evv.toEnumVariant();
|
||||||
|
m_pIEnumVARIANT = tmp.m_pIEnumVARIANT;
|
||||||
|
tmp.m_pIEnumVARIANT = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements java.util.Enumeration
|
||||||
|
*
|
||||||
|
* @return boolean true if there are more elements in this enumeration
|
||||||
|
*/
|
||||||
|
public boolean hasMoreElements() {
|
||||||
|
{
|
||||||
|
if (m_recBuf[0] == null) {
|
||||||
|
if (this.Next(m_recBuf) <= 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements java.util.Enumeration
|
||||||
|
*
|
||||||
|
* @return next element in the enumeration
|
||||||
|
*/
|
||||||
|
public Variant nextElement() {
|
||||||
|
Variant last = m_recBuf[0];
|
||||||
|
if (last == null) {
|
||||||
|
if (this.Next(m_recBuf) <= 0)
|
||||||
|
throw new java.util.NoSuchElementException();
|
||||||
|
last = m_recBuf[0];
|
||||||
|
}
|
||||||
|
m_recBuf[0] = null;
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get next element in collection or null if at end
|
||||||
|
*
|
||||||
|
* @return Variant that is next in the collection
|
||||||
|
* @deprecated use nextElement() instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public Variant Next() {
|
||||||
|
if (hasMoreElements())
|
||||||
|
return nextElement();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This should be private and wrapped to protect JNI layer.
|
||||||
|
*
|
||||||
|
* @param receiverArray
|
||||||
|
* @return Returns the next variant object pointer as an int from windows
|
||||||
|
* layer
|
||||||
|
*/
|
||||||
|
public native int Next(Variant[] receiverArray);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This should be private and wrapped to protect JNI layer.
|
||||||
|
*
|
||||||
|
* @param count
|
||||||
|
* number to skip
|
||||||
|
*/
|
||||||
|
public native void Skip(int count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This should be private and wrapped to protect JNI layer
|
||||||
|
*/
|
||||||
|
public native void Reset();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* now private so only this object can access was: call this to explicitly
|
||||||
|
* release the com object before gc
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private native void release();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#finalize()
|
||||||
|
*/
|
||||||
|
protected void finalize() {
|
||||||
|
safeRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.jacob.com.JacobObject#safeRelease()
|
||||||
|
*/
|
||||||
|
public void safeRelease() {
|
||||||
|
super.safeRelease();
|
||||||
|
if (m_pIEnumVARIANT != 0) {
|
||||||
|
this.release();
|
||||||
|
m_pIEnumVARIANT = 0;
|
||||||
|
} else {
|
||||||
|
// looks like a double release
|
||||||
|
if (isDebugEnabled()) {
|
||||||
|
debug(this.getClass().getName() + ":" + this.hashCode()
|
||||||
|
+ " double release");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
108
java/src/com/jacob/com/InvocationProxy.java
Normal file
108
java/src/com/jacob/com/InvocationProxy.java
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version $Id$
|
||||||
|
* @author joe
|
||||||
|
*
|
||||||
|
* DispatchEvents wraps this class around any event handlers before making the
|
||||||
|
* JNI call that sets up the link with EventProxy. This means that
|
||||||
|
* EventProxy.cpp just calls invoke(String,Variant[]) against the instance of
|
||||||
|
* this class. Then this class does reflection against the event listener to
|
||||||
|
* call the actual event methods. The event methods can return void or return a
|
||||||
|
* Variant. Any value returned will be passed back to the calling windows module
|
||||||
|
* by the Jacob JNI layer.
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* The void returning signature is the standard legacy signature. The Variant
|
||||||
|
* returning signature was added in 1.10 to support event handlers returning
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class InvocationProxy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the object we will try and forward to.
|
||||||
|
*/
|
||||||
|
protected Object mTargetObject = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dummy constructor for subclasses that don't actually wrap anything and
|
||||||
|
* just want to override the invoke() method
|
||||||
|
*/
|
||||||
|
protected InvocationProxy() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The method actually invoked by EventProxy.cpp. The method name is
|
||||||
|
* calculated by the underlying JNI code from the MS windows Callback
|
||||||
|
* function name. The method is assumed to take an array of Variant objects.
|
||||||
|
* The method may return a Variant or be a void. Those are the only two
|
||||||
|
* options that will not blow up.
|
||||||
|
* <p>
|
||||||
|
* Subclasses that override this should make sure mTargetObject is not null
|
||||||
|
* before processing.
|
||||||
|
*
|
||||||
|
* @param methodName
|
||||||
|
* name of method in mTargetObject we will invoke
|
||||||
|
* @param targetParameters
|
||||||
|
* Variant[] that is the single parameter to the method
|
||||||
|
* @return an object that will be returned to the com event caller
|
||||||
|
*/
|
||||||
|
public abstract Variant invoke(String methodName,
|
||||||
|
Variant targetParameters[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used by EventProxy.cpp to create variant objects in the right thread
|
||||||
|
*
|
||||||
|
* @return Variant object that will be used by the COM layer
|
||||||
|
*/
|
||||||
|
public Variant getVariant() {
|
||||||
|
return new VariantViaEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the target for this InvocationProxy.
|
||||||
|
*
|
||||||
|
* @param pTargetObject
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if target is not publicly accessible
|
||||||
|
*/
|
||||||
|
public void setTarget(Object pTargetObject) {
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("InvocationProxy: setting target "
|
||||||
|
+ pTargetObject);
|
||||||
|
}
|
||||||
|
if (pTargetObject != null) {
|
||||||
|
// JNI code apparently bypasses this check and could operate against
|
||||||
|
// protected classes. This seems like a security issue...
|
||||||
|
// maybe it was because JNI code isn't in a package?
|
||||||
|
if (!java.lang.reflect.Modifier.isPublic(pTargetObject.getClass()
|
||||||
|
.getModifiers())) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"InvocationProxy only public classes can receive event notifications");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mTargetObject = pTargetObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
123
java/src/com/jacob/com/InvocationProxyAllVariants.java
Normal file
123
java/src/com/jacob/com/InvocationProxyAllVariants.java
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class acts as a proxy between the windows event callback mechanism and
|
||||||
|
* the Java classes that are looking for events. It assumes that all of the Java
|
||||||
|
* classes that are looking for events implement methods with the same names as
|
||||||
|
* the windows events and that the implemented methods accept an array of
|
||||||
|
* variant objects. The methods can return void or a Variant that will be
|
||||||
|
* returned to the calling layer. All Event methods that will be recognized by
|
||||||
|
* InvocationProxyAllEvents have the signature
|
||||||
|
*
|
||||||
|
* <code> void eventMethodName(Variant[])</code> or
|
||||||
|
* <code> Variant eventMethodName(Variant[])</code>
|
||||||
|
*/
|
||||||
|
public class InvocationProxyAllVariants extends InvocationProxy {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.jacob.com.InvocationProxy#invoke(java.lang.String,
|
||||||
|
* com.jacob.com.Variant[])
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Variant invoke(String methodName, Variant targetParameters[]) {
|
||||||
|
Variant mVariantToBeReturned = null;
|
||||||
|
if (mTargetObject == null) {
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("InvocationProxy: received notification ("
|
||||||
|
+ methodName + ") with no target set");
|
||||||
|
}
|
||||||
|
// structured programming guidlines say this return should not be up
|
||||||
|
// here
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Class targetClass = mTargetObject.getClass();
|
||||||
|
if (methodName == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"InvocationProxy: missing method name");
|
||||||
|
}
|
||||||
|
if (targetParameters == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"InvocationProxy: missing Variant parameters");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("InvocationProxy: trying to invoke "
|
||||||
|
+ methodName + " on " + mTargetObject);
|
||||||
|
}
|
||||||
|
Method targetMethod;
|
||||||
|
targetMethod = targetClass.getMethod(methodName,
|
||||||
|
new Class[] { Variant[].class });
|
||||||
|
if (targetMethod != null) {
|
||||||
|
// protected classes can't be invoked against even if they
|
||||||
|
// let you grab the method. you could do
|
||||||
|
// targetMethod.setAccessible(true);
|
||||||
|
// but that should be stopped by the security manager
|
||||||
|
Object mReturnedByInvocation = null;
|
||||||
|
mReturnedByInvocation = targetMethod.invoke(mTargetObject,
|
||||||
|
new Object[] { targetParameters });
|
||||||
|
if (mReturnedByInvocation == null) {
|
||||||
|
mVariantToBeReturned = null;
|
||||||
|
} else if (!(mReturnedByInvocation instanceof Variant)) {
|
||||||
|
// could try and convert to Variant here.
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"InvocationProxy: invokation of target method returned "
|
||||||
|
+ "non-null non-variant object: "
|
||||||
|
+ mReturnedByInvocation);
|
||||||
|
} else {
|
||||||
|
mVariantToBeReturned = (Variant) mReturnedByInvocation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
// what causes this exception?
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
// this happens whenever the listener doesn't implement all the
|
||||||
|
// methods
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("InvocationProxy: listener (" + mTargetObject
|
||||||
|
+ ") doesn't implement " + methodName);
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
// we can throw these inside the catch block so need to re-throw it
|
||||||
|
throw e;
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
// can't access the method on the target instance for some reason
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject
|
||||||
|
.debug("InvocationProxy: probably tried to access public method on non public class"
|
||||||
|
+ methodName);
|
||||||
|
}
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
// invocation of target method failed
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return mVariantToBeReturned;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
49
java/src/com/jacob/com/JacobException.java
Normal file
49
java/src/com/jacob/com/JacobException.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parent class of all Jacob exceptions. They all used to be based off of
|
||||||
|
* RuntimeException or ComException but it was decided to base them all off of
|
||||||
|
* one owned by this project.
|
||||||
|
*/
|
||||||
|
public class JacobException extends RuntimeException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -1637125318746002715L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor. Calls super with a "No Message Provided" string
|
||||||
|
*/
|
||||||
|
public JacobException() {
|
||||||
|
super("No Message Provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* standard constructor
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public JacobException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
110
java/src/com/jacob/com/JacobObject.java
Normal file
110
java/src/com/jacob/com/JacobObject.java
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The superclass of all Jacob objects. It is used to create a standard API
|
||||||
|
* framework and to facilitate memory management for Java and COM memory
|
||||||
|
* elements.
|
||||||
|
* <p>
|
||||||
|
* All instances of this class and subclasses are automatically managed by the
|
||||||
|
* ROT. This means the ROT cannot be a subclass of JacobObject.
|
||||||
|
* <p>
|
||||||
|
* All COM object created by JACOB extend this class so that we can
|
||||||
|
* automatically release them when the thread is detached from COM - if we leave
|
||||||
|
* it to the finalizer it will call the release from another thread, which may
|
||||||
|
* result in a segmentation violation.
|
||||||
|
*/
|
||||||
|
public class JacobObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard constructor that adds this JacobObject to the memory management
|
||||||
|
* pool.
|
||||||
|
*/
|
||||||
|
public JacobObject() {
|
||||||
|
ROT.addObject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finalizers call this method. This method should release any COM data
|
||||||
|
* structures in a way that it can be called multiple times. This can happen
|
||||||
|
* if someone manually calls this and then a finalizer calls it.
|
||||||
|
*/
|
||||||
|
public void safeRelease() {
|
||||||
|
// currently does nothing - subclasses may do something
|
||||||
|
if (isDebugEnabled()) {
|
||||||
|
// this used to do a toString() but that is bad for SafeArray
|
||||||
|
debug("SafeRelease: " + this.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When things go wrong, it is useful to be able to debug the ROT.
|
||||||
|
*/
|
||||||
|
private static final boolean DEBUG =
|
||||||
|
// true;
|
||||||
|
"true".equalsIgnoreCase(System.getProperty("com.jacob.debug"));
|
||||||
|
|
||||||
|
protected static boolean isDebugEnabled() {
|
||||||
|
return DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads JacobVersion.Properties and returns the value of version in it
|
||||||
|
*
|
||||||
|
* @deprecated use JacobReleaseInfo.getBuildDate() instead.
|
||||||
|
* @return String value of version in JacobVersion.Properties or "" if none
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static String getBuildDate() {
|
||||||
|
return JacobReleaseInfo.getBuildDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads JacobVersion.Properties and returns the value of version in it
|
||||||
|
*
|
||||||
|
* @deprecated use JacobReleaseInfo.getBuildVersion() instead.
|
||||||
|
* @return String value of version in JacobVersion.Properties or "" if none
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static String getBuildVersion() {
|
||||||
|
return JacobReleaseInfo.getBuildVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Very basic debugging function.
|
||||||
|
*
|
||||||
|
* @param istrMessage
|
||||||
|
*/
|
||||||
|
protected static void debug(String istrMessage) {
|
||||||
|
if (isDebugEnabled()) {
|
||||||
|
System.out.println(Thread.currentThread().getName() + ": "
|
||||||
|
+ istrMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* force the jacob DLL to be loaded whenever this class is referenced
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
LibraryLoader.loadJacobLibrary();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
96
java/src/com/jacob/com/JacobReleaseInfo.java
Normal file
96
java/src/com/jacob/com/JacobReleaseInfo.java
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to the version properties file. This code was removed from
|
||||||
|
* JacobObject because it doesn't belong there.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class JacobReleaseInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* holds the build version as retrieved from the version properties file
|
||||||
|
* that exists in the JAR. This can be retrieved by calling the static
|
||||||
|
* method getBuildVersion()
|
||||||
|
*
|
||||||
|
* @see #getBuildVersion()
|
||||||
|
*/
|
||||||
|
private static String buildVersion = "";
|
||||||
|
/**
|
||||||
|
* holds the build date as retrieved from the version properties file that
|
||||||
|
* exists in the JAR This can be retrieved by calling the static method
|
||||||
|
* getBuildDate()
|
||||||
|
*
|
||||||
|
* @see #getBuildDate()
|
||||||
|
*/
|
||||||
|
private static String buildDate = "";
|
||||||
|
/** the name of the jacob version properties file */
|
||||||
|
private static final String PROPERTY_FILE_NAME = "META-INF/JacobVersion.properties";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads version information from PROPERTY_FILE_NAME that was built as part
|
||||||
|
* of this release.
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException
|
||||||
|
* when it can't find the version properties file
|
||||||
|
*/
|
||||||
|
private static void loadVersionProperties() {
|
||||||
|
/*Properties versionProps = new Properties();
|
||||||
|
// can't use system class loader cause won't work in JavaWebStart
|
||||||
|
InputStream stream = JacobReleaseInfo.class.getClassLoader()
|
||||||
|
.getResourceAsStream(PROPERTY_FILE_NAME);
|
||||||
|
// This should never happen. This is an attempt to make something work
|
||||||
|
// for WebSphere. They may be using some kind of Servlet loader that
|
||||||
|
// needs an absolute path based search
|
||||||
|
if (stream == null) {
|
||||||
|
stream = JacobReleaseInfo.class.getClassLoader()
|
||||||
|
.getResourceAsStream("/" + PROPERTY_FILE_NAME);
|
||||||
|
}
|
||||||
|
// A report came in that WebSphere had trouble finding the file
|
||||||
|
// so lets trap it. Plus, it's a good idea anyway.
|
||||||
|
if (stream == null) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Can't find "
|
||||||
|
+ PROPERTY_FILE_NAME
|
||||||
|
+ " using JacobReleaseInfo.class.getClassLoader().getResourceAsStream()");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
versionProps.load(stream);
|
||||||
|
stream.close();
|
||||||
|
buildVersion = (String) versionProps.get("version");
|
||||||
|
buildDate = (String) versionProps.get("build.date");
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
ioe.printStackTrace();
|
||||||
|
System.err.println("Warning! Couldn't load props " + ioe);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* loads PROPERT_FILE_NAME and returns the value of version in it
|
||||||
|
*
|
||||||
|
* @return String value of version in PROPERT_FILE_NAME or "" if none
|
||||||
|
*/
|
||||||
|
public static String getBuildDate() {
|
||||||
|
if (buildDate.equals("")) {
|
||||||
|
loadVersionProperties();
|
||||||
|
}
|
||||||
|
return buildDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* loads PROPERT_FILE_NAME and returns the value of version in it
|
||||||
|
*
|
||||||
|
* @return String value of version in PROPERT_FILE_NAME or "" if none
|
||||||
|
*/
|
||||||
|
public static String getBuildVersion() {
|
||||||
|
if (buildVersion.equals("")) {
|
||||||
|
loadVersionProperties();
|
||||||
|
}
|
||||||
|
return buildVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
230
java/src/com/jacob/com/LibraryLoader.java
Normal file
230
java/src/com/jacob/com/LibraryLoader.java
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2007 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to centralize the way in which the jacob JNI library is loaded.
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* This supports defining the path or library name using system properties or a
|
||||||
|
* custom resource file. If desired, jacob can auto-detect the correct version
|
||||||
|
* of the DLL for 32 or 64 bit windows, as long as you have named them
|
||||||
|
* differently.
|
||||||
|
*
|
||||||
|
* <ol>
|
||||||
|
* <li> If system property {@link #JACOB_DLL_PATH} is defined, the file located
|
||||||
|
* there will be loaded as the jacob dll using System.load(). </li>
|
||||||
|
*
|
||||||
|
* <li> If system property {@link #JACOB_DLL_NAME} is defined, the file located
|
||||||
|
* there will be loaded as the jacob dll. </li>
|
||||||
|
* <li> If system property {@link #JACOB_DLL_NAME_X86} and
|
||||||
|
* {@link #JACOB_DLL_NAME_X64} are defined, the file located there will be
|
||||||
|
* loaded as the jacob dll, depending on the version of Windows. </li>
|
||||||
|
*
|
||||||
|
* <li> If {@link #JACOB_DLL_NAME} is defined in the
|
||||||
|
* {@code com.jacob.com.JacobLibraryLoader} resource file, the specified dll
|
||||||
|
* will be loaded from the {@code java.library.path}. </li>
|
||||||
|
* <li> If {@link #JACOB_DLL_NAME_X86} and {@link #JACOB_DLL_NAME_X64} are
|
||||||
|
* defined in the {@code com.jacob.com.JacobLibraryLoader} resource file, the
|
||||||
|
* specified dll will be loaded from the {@code java.library.path}, depending
|
||||||
|
* on the version of Windows. </li>
|
||||||
|
*
|
||||||
|
* <li> If none of the above are true, the default is to load the library named
|
||||||
|
* "jacob-<version>-<arch>" (or
|
||||||
|
* "jacob-<version>-<arch&rt;.dll") from the {@code java.library.path}.
|
||||||
|
* </li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* The standard behavior for most applications is that {@code LoadLibrary()}
|
||||||
|
* will be called to load the dll. {@code LoadLibary()} searches directories
|
||||||
|
* specified in the variable {@code java.library.path}. This is why most test
|
||||||
|
* cases specify -Djava.library.path in their command line arguments.
|
||||||
|
* <p>
|
||||||
|
* JACOB_DLL_PATH submitted sourceforge ticket 1493647 Added 1.11 <br>
|
||||||
|
* JACOB_DLL_NAME, JACOB_DLL_NAME_32, JACOB_DLL_NAME_64 submitted sourceforge
|
||||||
|
* ticket 1845039 Added 1.14M7
|
||||||
|
*
|
||||||
|
* @author Scott Dickerson (sjd78)
|
||||||
|
* @author Jason Smith
|
||||||
|
*/
|
||||||
|
public final class LibraryLoader {
|
||||||
|
/**
|
||||||
|
* Name of system property (currently <tt>jacob.dll.path</tt>) that may
|
||||||
|
* contain an absolute path to the JNI library.
|
||||||
|
*/
|
||||||
|
public static final String JACOB_DLL_PATH = "jacob.dll.path";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of system property (currently <tt>jacob.dll.name</tt>) that may
|
||||||
|
* contain an alternate name for the JNI library (default is 'jacob').
|
||||||
|
*/
|
||||||
|
public static final String JACOB_DLL_NAME = "jacob.dll.name";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of system property (currently <tt>jacob.dll.name</tt>) that may
|
||||||
|
* contain an alternate name for the JNI library (default is 'jacob'), 32
|
||||||
|
* bit windows.
|
||||||
|
*/
|
||||||
|
public static final String JACOB_DLL_NAME_X86 = "jacob.dll.name.x86";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of system property (currently <tt>jacob.dll.name</tt>) that may
|
||||||
|
* contain an alternate name for the JNI library (default is 'jacob'), 64
|
||||||
|
* bit windows.
|
||||||
|
*/
|
||||||
|
public static final String JACOB_DLL_NAME_X64 = "jacob.dll.name.x64";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appended to "jacob" when building DLL name This string must EXACTLY match
|
||||||
|
* the string in the build.xml file
|
||||||
|
*/
|
||||||
|
public static final String DLL_NAME_MODIFIER_32_BIT = "x86";
|
||||||
|
/**
|
||||||
|
* Appended to "jacob" when building DLL name This string must EXACTLY match
|
||||||
|
* the string in the build.xml file
|
||||||
|
*/
|
||||||
|
public static final String DLL_NAME_MODIFIER_64_BIT = "x64";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the jacob dll either from an absolute path or by a library name,
|
||||||
|
* both of which may be defined in various ways.
|
||||||
|
*
|
||||||
|
* @throws UnsatisfiedLinkError
|
||||||
|
* if the library does not exist.
|
||||||
|
*/
|
||||||
|
public static void loadJacobLibrary() {
|
||||||
|
// In some cases, a library that uses Jacob won't be able to set system
|
||||||
|
// properties
|
||||||
|
// prior to Jacob being loaded. The resource bundle provides an
|
||||||
|
// alternate way to
|
||||||
|
// override DLL name or path that will be loaded with Jacob regardless
|
||||||
|
// of other
|
||||||
|
// initialization order.
|
||||||
|
ResourceBundle resources = null;
|
||||||
|
Set<String> keys = new HashSet<String>();
|
||||||
|
try {
|
||||||
|
resources = ResourceBundle.getBundle(LibraryLoader.class.getName(),
|
||||||
|
Locale.getDefault(), LibraryLoader.class.getClassLoader());
|
||||||
|
for (Enumeration<String> i = resources.getKeys(); i
|
||||||
|
.hasMoreElements();) {
|
||||||
|
String key = i.nextElement();
|
||||||
|
keys.add(key);
|
||||||
|
}
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
// Do nothing. Expected.
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, check for a defined PATH. System property overrides resource
|
||||||
|
// bundle.
|
||||||
|
String path = System.getProperty(JACOB_DLL_PATH);
|
||||||
|
if (path == null && resources != null && keys.contains(JACOB_DLL_PATH)) {
|
||||||
|
path = (String) resources.getObject(JACOB_DLL_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path != null) {
|
||||||
|
JacobObject.debug("Loading library " + path
|
||||||
|
+ " using System.loadLibrary ");
|
||||||
|
System.load(path);
|
||||||
|
} else {
|
||||||
|
// Path was not defined, so use the OS mechanism for loading
|
||||||
|
// libraries.
|
||||||
|
// Check for a defined NAME. System property overrides resource
|
||||||
|
// bundle.
|
||||||
|
String name = null;
|
||||||
|
|
||||||
|
if (System.getProperty(JACOB_DLL_NAME) != null) {
|
||||||
|
name = System.getProperty(JACOB_DLL_NAME);
|
||||||
|
} else if (System.getProperty(JACOB_DLL_NAME_X86) != null
|
||||||
|
&& shouldLoad32Bit()) {
|
||||||
|
name = System.getProperty(JACOB_DLL_NAME_X86);
|
||||||
|
} else if (System.getProperty(JACOB_DLL_NAME_X64) != null
|
||||||
|
&& !shouldLoad32Bit()) {
|
||||||
|
name = System.getProperty(JACOB_DLL_NAME_X64);
|
||||||
|
} else if (resources != null && keys.contains(JACOB_DLL_NAME)) {
|
||||||
|
name = resources.getString(JACOB_DLL_NAME);
|
||||||
|
} else if (resources != null && keys.contains(JACOB_DLL_NAME_X86)
|
||||||
|
&& shouldLoad32Bit()) {
|
||||||
|
name = resources.getString(JACOB_DLL_NAME_X86);
|
||||||
|
} else if (resources != null && keys.contains(JACOB_DLL_NAME_X64)
|
||||||
|
&& !shouldLoad32Bit()) {
|
||||||
|
name = resources.getString(JACOB_DLL_NAME_X64);
|
||||||
|
} else {
|
||||||
|
// No alternate NAME or PATH was defined, so use the default.
|
||||||
|
// We will almost always end up here.
|
||||||
|
name = getPreferredDLLName();
|
||||||
|
}
|
||||||
|
|
||||||
|
JacobObject.debug("Loading library " + name
|
||||||
|
+ " using System.loadLibrary ");
|
||||||
|
// System.out.println("Loading " + name);
|
||||||
|
System.loadLibrary(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Developer note: This method MUST be synchronized with the DLL names
|
||||||
|
* created as part of the build process in build.xml
|
||||||
|
* <p>
|
||||||
|
* The DLL name is "jacob\<PLATFORM\>.release"
|
||||||
|
*
|
||||||
|
* @return the preferred name of the DLL adjusted for this platform and
|
||||||
|
* version without the ".dll" extension
|
||||||
|
*/
|
||||||
|
public static String getPreferredDLLName() {
|
||||||
|
if (shouldLoad32Bit()) {
|
||||||
|
return "jacob" + "-" + JacobReleaseInfo.getBuildVersion() + "-"
|
||||||
|
+ DLL_NAME_MODIFIER_32_BIT;
|
||||||
|
} else {
|
||||||
|
return "jacob" + "-" + JacobReleaseInfo.getBuildVersion() + "-"
|
||||||
|
+ DLL_NAME_MODIFIER_64_BIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects whether this is a 32-bit JVM.
|
||||||
|
*
|
||||||
|
* @return {@code true} if this is a 32-bit JVM.
|
||||||
|
*/
|
||||||
|
protected static boolean shouldLoad32Bit() {
|
||||||
|
// This guesses whether we are running 32 or 64 bit Java.
|
||||||
|
// This works for Sun and IBM JVMs version 5.0 or later.
|
||||||
|
// May need to be adjusted for non-Sun JVMs.
|
||||||
|
|
||||||
|
String bits = System.getProperty("sun.arch.data.model", "?");
|
||||||
|
if (bits.equals("32"))
|
||||||
|
return true;
|
||||||
|
else if (bits.equals("64"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// this works for jRocket
|
||||||
|
String arch = System.getProperty("java.vm.name", "?");
|
||||||
|
if (arch.toLowerCase().indexOf("64-bit") >= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // LibraryLoader
|
||||||
29
java/src/com/jacob/com/MainSTA.java
Normal file
29
java/src/com/jacob/com/MainSTA.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We provide our own main sta thread to avoid COM tagging a random thread as
|
||||||
|
* the main STA - this is the thread in which all Apartment threaded components
|
||||||
|
* will be created if the client chooses an MTA threading model for the java
|
||||||
|
* side of the app.
|
||||||
|
*/
|
||||||
|
public class MainSTA extends STA {
|
||||||
|
}
|
||||||
41
java/src/com/jacob/com/NotImplementedException.java
Normal file
41
java/src/com/jacob/com/NotImplementedException.java
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown by java APIs that are not implemented either because they were never
|
||||||
|
* implemented or because they are being deprecated This is a subclass of
|
||||||
|
* ComException so callers can still just catch ComException.
|
||||||
|
*/
|
||||||
|
public class NotImplementedException extends JacobException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -9169900832852356445L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param description
|
||||||
|
*/
|
||||||
|
public NotImplementedException(String description) {
|
||||||
|
super(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
279
java/src/com/jacob/com/ROT.java
Normal file
279
java/src/com/jacob/com/ROT.java
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Running Object Table (ROT) maps each thread to a collection of all the
|
||||||
|
* JacobObjects that were created in that thread. It always operates on the
|
||||||
|
* current thread so all the methods are static and they implicitly get the
|
||||||
|
* current thread.
|
||||||
|
* <p>
|
||||||
|
* The clearObjects method is used to release all the COM objects created by
|
||||||
|
* Jacob in the current thread prior to uninitializing COM for that thread.
|
||||||
|
* <p>
|
||||||
|
* Prior to 1.9, manual garbage collection was the only option in Jacob, but
|
||||||
|
* from 1.9 onward, setting the com.jacob.autogc system property allows the
|
||||||
|
* objects referenced by the ROT to be automatically GCed. Automatic GC may be
|
||||||
|
* preferable in systems with heavy event callbacks.
|
||||||
|
* <p>
|
||||||
|
* Is [ 1116101 ] jacob-msg 0284 relevant???
|
||||||
|
*/
|
||||||
|
public abstract class ROT {
|
||||||
|
/**
|
||||||
|
* Manual garbage collection was the only option pre 1.9 Can staticly cache
|
||||||
|
* the results because only one value and we don't let it change during a
|
||||||
|
* run
|
||||||
|
*/
|
||||||
|
protected static final boolean USE_AUTOMATIC_GARBAGE_COLLECTION = "true"
|
||||||
|
.equalsIgnoreCase(System.getProperty("com.jacob.autogc"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the code is ran from an applet that is called from javascript the Java
|
||||||
|
* Plugin does not give full permissions to the code and thus System
|
||||||
|
* properties cannot be accessed. They can be accessed at class
|
||||||
|
* initialization time.
|
||||||
|
*
|
||||||
|
* The default behavior is to include all classes in the ROT, setting a
|
||||||
|
* boolean here to indicate this prevents a call to System.getProperty as
|
||||||
|
* part of the general call flow.
|
||||||
|
*/
|
||||||
|
protected static final Boolean INCLUDE_ALL_CLASSES_IN_ROT = Boolean
|
||||||
|
.valueOf(System.getProperty("com.jacob.includeAllClassesInROT",
|
||||||
|
"true"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suffix added to class name to make up property name that determines if
|
||||||
|
* this object should be stored in the ROT. This 1.13 "feature" makes it
|
||||||
|
* possible to cause VariantViaEvent objects to not be added to the ROT in
|
||||||
|
* event callbacks.
|
||||||
|
* <p>
|
||||||
|
* We don't have a static for the actual property because there is a
|
||||||
|
* different property for each class that may make use of this feature.
|
||||||
|
*/
|
||||||
|
protected static String PUT_IN_ROT_SUFFIX = ".PutInROT";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A hash table where each element is another HashMap that represents a
|
||||||
|
* thread. Each thread HashMap contains the com objects created in that
|
||||||
|
* thread
|
||||||
|
*/
|
||||||
|
private static HashMap<String, Map<JacobObject, String>> rot = new HashMap<String, Map<JacobObject, String>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds a new thread storage area to rot
|
||||||
|
*
|
||||||
|
* @return Map corresponding to the thread that this call was made in
|
||||||
|
*/
|
||||||
|
protected synchronized static Map<JacobObject, String> addThread() {
|
||||||
|
// should use the id here instead of the name because the name can be
|
||||||
|
// changed
|
||||||
|
String t_name = Thread.currentThread().getName();
|
||||||
|
if (rot.containsKey(t_name)) {
|
||||||
|
// nothing to do
|
||||||
|
} else {
|
||||||
|
Map<JacobObject, String> tab = null;
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ROT: Automatic GC flag == "
|
||||||
|
+ USE_AUTOMATIC_GARBAGE_COLLECTION);
|
||||||
|
}
|
||||||
|
if (!USE_AUTOMATIC_GARBAGE_COLLECTION) {
|
||||||
|
tab = new HashMap<JacobObject, String>();
|
||||||
|
} else {
|
||||||
|
tab = new WeakHashMap<JacobObject, String>();
|
||||||
|
}
|
||||||
|
rot.put(t_name, tab);
|
||||||
|
}
|
||||||
|
return getThreadObjects(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the pool for this thread if it exists. can create a new one if
|
||||||
|
* you wish by passing in TRUE
|
||||||
|
*
|
||||||
|
* @param createIfDoesNotExist
|
||||||
|
* @return Map the collection that holds the objects created in the current
|
||||||
|
* thread
|
||||||
|
*/
|
||||||
|
protected synchronized static Map<JacobObject, String> getThreadObjects(
|
||||||
|
boolean createIfDoesNotExist) {
|
||||||
|
String t_name = Thread.currentThread().getName();
|
||||||
|
if (!rot.containsKey(t_name) && createIfDoesNotExist) {
|
||||||
|
addThread();
|
||||||
|
}
|
||||||
|
return rot.get(t_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates across all of the entries in the Hashmap in the rot that
|
||||||
|
* corresponds to this thread. This calls safeRelease() on each entry and
|
||||||
|
* then clears the map when done and removes it from the rot. All traces of
|
||||||
|
* this thread's objects will disappear. This is called by COMThread in the
|
||||||
|
* tear down and provides a synchronous way of releasing memory
|
||||||
|
*/
|
||||||
|
protected static void clearObjects() {
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ROT: " + rot.keySet().size()
|
||||||
|
+ " thread tables exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<JacobObject, String> tab = getThreadObjects(false);
|
||||||
|
if (tab != null) {
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ROT: " + tab.keySet().size()
|
||||||
|
+ " objects to clear in this thread's ROT ");
|
||||||
|
}
|
||||||
|
// walk the values
|
||||||
|
Iterator<JacobObject> it = tab.keySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
JacobObject o = it.next();
|
||||||
|
if (o != null
|
||||||
|
// can't use this cause creates a Variant if calling SafeAray
|
||||||
|
// and we get an exception modifying the collection while
|
||||||
|
// iterating
|
||||||
|
// && o.toString() != null
|
||||||
|
) {
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
if (o instanceof SafeArray) {
|
||||||
|
// SafeArray create more objects when calling
|
||||||
|
// toString()
|
||||||
|
// which causes a concurrent modification exception
|
||||||
|
// in HashMap
|
||||||
|
JacobObject.debug("ROT: removing "
|
||||||
|
+ o.getClass().getName());
|
||||||
|
} else {
|
||||||
|
// Variant toString() is probably always bad in here
|
||||||
|
JacobObject.debug("ROT: removing " + o.hashCode()
|
||||||
|
+ "->" + o.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
o.safeRelease();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// empty the collection
|
||||||
|
tab.clear();
|
||||||
|
// remove the collection from rot
|
||||||
|
ROT.removeThread();
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ROT: thread table cleared and removed");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ROT: nothing to clear!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the map from the rot that is associated with the current thread.
|
||||||
|
*/
|
||||||
|
private synchronized static void removeThread() {
|
||||||
|
// should this see if it exists first?
|
||||||
|
rot.remove(Thread.currentThread().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated the java model leave the responsibility of clearing up
|
||||||
|
* objects to the Garbage Collector. Our programming model
|
||||||
|
* should not require that the user specifically remove object
|
||||||
|
* from the thread. <br>
|
||||||
|
* This will remove an object from the ROT <br>
|
||||||
|
* This does not need to be synchronized because only the rot
|
||||||
|
* modification related methods need to synchronized. Each
|
||||||
|
* individual map is only modified in a single thread.
|
||||||
|
* @param o
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
protected static void removeObject(JacobObject o) {
|
||||||
|
Map<JacobObject, String> tab = ROT.getThreadObjects(false);
|
||||||
|
if (tab != null) {
|
||||||
|
tab.remove(o);
|
||||||
|
}
|
||||||
|
o.safeRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an object to the HashMap for the current thread. <br>
|
||||||
|
* <p>
|
||||||
|
* This method does not need to be threaded because the only concurrent
|
||||||
|
* modification risk is on the hash map that contains all of the thread
|
||||||
|
* related hash maps. The individual thread related maps are only used on a
|
||||||
|
* per thread basis so there isn't a locking issue.
|
||||||
|
* <p>
|
||||||
|
* In addition, this method cannot be threaded because it calls
|
||||||
|
* ComThread.InitMTA. The ComThread object has some methods that call ROT so
|
||||||
|
* we could end up deadlocked. This method should be safe without the
|
||||||
|
* synchronization because the ROT works on per thread basis and the methods
|
||||||
|
* that add threads and remove thread related entries are all synchronized
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param o
|
||||||
|
*/
|
||||||
|
protected static void addObject(JacobObject o) {
|
||||||
|
String shouldIncludeClassInROT = "true";
|
||||||
|
// only call System.getProperty if we are not including all classes in
|
||||||
|
// the ROT. This lets us run with standard Jacob behavior in Applets
|
||||||
|
// without the security exception raised by System.getProperty in the
|
||||||
|
// flow
|
||||||
|
if (!ROT.INCLUDE_ALL_CLASSES_IN_ROT) {
|
||||||
|
shouldIncludeClassInROT = System.getProperty(o.getClass().getName()
|
||||||
|
+ PUT_IN_ROT_SUFFIX, "true");
|
||||||
|
}
|
||||||
|
if (shouldIncludeClassInROT.equalsIgnoreCase("false")) {
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("JacobObject: New instance of "
|
||||||
|
+ o.getClass().getName() + " not added to ROT");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// first see if we have a table for this thread
|
||||||
|
Map<JacobObject, String> tab = getThreadObjects(false);
|
||||||
|
if (tab == null) {
|
||||||
|
// this thread has not been initialized as a COM thread
|
||||||
|
// so make it part of MTA for backwards compatibility
|
||||||
|
ComThread.InitMTA(false);
|
||||||
|
// don't really need the "true" because the InitMTA will have
|
||||||
|
// called back to the ROT to create a table for this thread
|
||||||
|
tab = getThreadObjects(true);
|
||||||
|
}
|
||||||
|
if (JacobObject.isDebugEnabled()) {
|
||||||
|
JacobObject.debug("ROT: adding " + o + "->"
|
||||||
|
+ o.getClass().getName()
|
||||||
|
+ " table size prior to addition:" + tab.size());
|
||||||
|
}
|
||||||
|
// add the object to the table that is specific to this thread
|
||||||
|
if (tab != null) {
|
||||||
|
tab.put(o, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ROT can't be a subclass of JacobObject because of the way ROT pools are
|
||||||
|
* managed so we force a DLL load here by referencing JacobObject
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
LibraryLoader.loadJacobLibrary();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
101
java/src/com/jacob/com/STA.java
Normal file
101
java/src/com/jacob/com/STA.java
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that implements a Single Threaded Apartment. Users will subclass this
|
||||||
|
* and override OnInit() and OnQuit() where they will create and destroy a COM
|
||||||
|
* component that wants to run in an STA other than the main STA.
|
||||||
|
*/
|
||||||
|
public class STA extends Thread {
|
||||||
|
/**
|
||||||
|
* referenced by STA.cpp
|
||||||
|
*/
|
||||||
|
public int threadID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor for STA
|
||||||
|
*/
|
||||||
|
public STA() {
|
||||||
|
start(); // start the thread
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see java.lang.Thread#run()
|
||||||
|
*/
|
||||||
|
public void run() {
|
||||||
|
// init COM
|
||||||
|
ComThread.InitSTA();
|
||||||
|
if (OnInit()) {
|
||||||
|
// this call blocks in the win32 message loop
|
||||||
|
// until quitMessagePump is called
|
||||||
|
doMessagePump();
|
||||||
|
}
|
||||||
|
OnQuit();
|
||||||
|
// uninit COM
|
||||||
|
ComThread.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method to create and initialize any COM component that you
|
||||||
|
* want to run in this thread. If anything fails, return false to terminate
|
||||||
|
* the thread.
|
||||||
|
*
|
||||||
|
* @return always returns true
|
||||||
|
*/
|
||||||
|
public boolean OnInit() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method to destroy any resource before the thread exits and
|
||||||
|
* COM in uninitialized
|
||||||
|
*/
|
||||||
|
public void OnQuit() {
|
||||||
|
// there is nothing to see here
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calls quitMessagePump
|
||||||
|
*/
|
||||||
|
public void quit() {
|
||||||
|
quitMessagePump();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* run a message pump for the main STA
|
||||||
|
*/
|
||||||
|
public native void doMessagePump();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* quit message pump for the main STA
|
||||||
|
*/
|
||||||
|
public native void quitMessagePump();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STA isn't a subclass of JacobObject so a reference to it doesn't load the
|
||||||
|
* DLL without this
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
LibraryLoader.loadJacobLibrary();
|
||||||
|
}
|
||||||
|
}
|
||||||
1172
java/src/com/jacob/com/SafeArray.java
Normal file
1172
java/src/com/jacob/com/SafeArray.java
Normal file
File diff suppressed because it is too large
Load Diff
2235
java/src/com/jacob/com/Variant.java
Normal file
2235
java/src/com/jacob/com/Variant.java
Normal file
File diff suppressed because it is too large
Load Diff
502
java/src/com/jacob/com/VariantUtilities.java
Normal file
502
java/src/com/jacob/com/VariantUtilities.java
Normal file
@@ -0,0 +1,502 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.math.MathContext;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility class used to convert between Java objects and Variants
|
||||||
|
*/
|
||||||
|
public final class VariantUtilities {
|
||||||
|
private VariantUtilities() {
|
||||||
|
// utility class with only static methods don't need constructors
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates a variant object from a java object. This method attempts to
|
||||||
|
* figure out the appropriate Variant type
|
||||||
|
*
|
||||||
|
* @param targetVariant
|
||||||
|
* @param pValueObject
|
||||||
|
* @param fByRef
|
||||||
|
*/
|
||||||
|
protected static void populateVariant(Variant targetVariant,
|
||||||
|
Object pValueObject, boolean fByRef) {
|
||||||
|
if (pValueObject == null) {
|
||||||
|
targetVariant.putEmpty();
|
||||||
|
} else if (pValueObject instanceof Integer) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putIntRef(((Integer) pValueObject).intValue());
|
||||||
|
} else {
|
||||||
|
targetVariant.putInt(((Integer) pValueObject).intValue());
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof Short) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putShortRef(((Short) pValueObject).shortValue());
|
||||||
|
} else {
|
||||||
|
targetVariant.putShort(((Short) pValueObject).shortValue());
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof String) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putStringRef((String) pValueObject);
|
||||||
|
} else {
|
||||||
|
targetVariant.putString((String) pValueObject);
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof Boolean) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putBooleanRef(((Boolean) pValueObject)
|
||||||
|
.booleanValue());
|
||||||
|
} else {
|
||||||
|
targetVariant.putBoolean(((Boolean) pValueObject)
|
||||||
|
.booleanValue());
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof Double) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putDoubleRef(((Double) pValueObject)
|
||||||
|
.doubleValue());
|
||||||
|
} else {
|
||||||
|
targetVariant.putDouble(((Double) pValueObject).doubleValue());
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof Float) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putFloatRef(((Float) pValueObject).floatValue());
|
||||||
|
} else {
|
||||||
|
targetVariant.putFloat(((Float) pValueObject).floatValue());
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof BigDecimal) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putDecimalRef(((BigDecimal) pValueObject));
|
||||||
|
} else {
|
||||||
|
targetVariant.putDecimal(((BigDecimal) pValueObject));
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof Byte) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putByteRef(((Byte) pValueObject).byteValue());
|
||||||
|
} else {
|
||||||
|
targetVariant.putByte(((Byte) pValueObject).byteValue());
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof Date) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putDateRef((Date) pValueObject);
|
||||||
|
} else {
|
||||||
|
targetVariant.putDate((Date) pValueObject);
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof Long) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putLongRef(((Long) pValueObject).longValue());
|
||||||
|
} else {
|
||||||
|
targetVariant.putLong(((Long) pValueObject).longValue());
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof Currency) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putCurrencyRef(((Currency) pValueObject));
|
||||||
|
} else {
|
||||||
|
targetVariant.putCurrency(((Currency) pValueObject));
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof SafeArray) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putSafeArrayRef((SafeArray) pValueObject);
|
||||||
|
} else {
|
||||||
|
targetVariant.putSafeArray((SafeArray) pValueObject);
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof Dispatch) {
|
||||||
|
if (fByRef) {
|
||||||
|
targetVariant.putDispatchRef((Dispatch) pValueObject);
|
||||||
|
} else {
|
||||||
|
targetVariant.putDispatch((Dispatch) pValueObject);
|
||||||
|
}
|
||||||
|
} else if (pValueObject instanceof Variant) {
|
||||||
|
// newly added 1.12-pre6 to support VT_VARIANT
|
||||||
|
targetVariant.putVariant(pValueObject);
|
||||||
|
} else {
|
||||||
|
// sourceforge patch 2171967
|
||||||
|
// used to rely on coercion but sometimes crashed VM
|
||||||
|
throw new NotImplementedException(
|
||||||
|
"populateVariant() not implemented for "
|
||||||
|
+ pValueObject.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map arguments based on msdn documentation. This method relies on the
|
||||||
|
* variant constructor except for arrays.
|
||||||
|
*
|
||||||
|
* @param objectToBeMadeIntoVariant
|
||||||
|
* @return Variant that represents the object
|
||||||
|
*/
|
||||||
|
protected static Variant objectToVariant(Object objectToBeMadeIntoVariant) {
|
||||||
|
if (objectToBeMadeIntoVariant == null) {
|
||||||
|
return new Variant();
|
||||||
|
} else if (objectToBeMadeIntoVariant instanceof Variant) {
|
||||||
|
// if a variant was passed in then be a slacker and just return it
|
||||||
|
return (Variant) objectToBeMadeIntoVariant;
|
||||||
|
} else if (objectToBeMadeIntoVariant.getClass().isArray()) {
|
||||||
|
// automatically convert arrays using reflection
|
||||||
|
// handle it differently based on the type of array
|
||||||
|
// added primitive support sourceforge 2762275
|
||||||
|
SafeArray sa = null;
|
||||||
|
int len1 = Array.getLength(objectToBeMadeIntoVariant);
|
||||||
|
Class componentType = objectToBeMadeIntoVariant.getClass()
|
||||||
|
.getComponentType();
|
||||||
|
|
||||||
|
if (componentType.isArray()) { // array of arrays
|
||||||
|
int max = 0;
|
||||||
|
for (int i = 0; i < len1; i++) {
|
||||||
|
Object e1 = Array.get(objectToBeMadeIntoVariant, i);
|
||||||
|
int len2 = Array.getLength(e1);
|
||||||
|
if (max < len2) {
|
||||||
|
max = len2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sa = new SafeArray(Variant.VariantVariant, len1, max);
|
||||||
|
for (int i = 0; i < len1; i++) {
|
||||||
|
Object e1 = Array.get(objectToBeMadeIntoVariant, i);
|
||||||
|
for (int j = 0; j < Array.getLength(e1); j++) {
|
||||||
|
sa.setVariant(i, j, objectToVariant(Array.get(e1, j)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (byte.class.equals(componentType)) {
|
||||||
|
byte[] arr = (byte[]) objectToBeMadeIntoVariant;
|
||||||
|
sa = new SafeArray(Variant.VariantByte, len1);
|
||||||
|
for (int i = 0; i < len1; i++) {
|
||||||
|
sa.setByte(i, arr[i]);
|
||||||
|
}
|
||||||
|
} else if (int.class.equals(componentType)) {
|
||||||
|
int[] arr = (int[]) objectToBeMadeIntoVariant;
|
||||||
|
sa = new SafeArray(Variant.VariantInt, len1);
|
||||||
|
for (int i = 0; i < len1; i++) {
|
||||||
|
sa.setInt(i, arr[i]);
|
||||||
|
}
|
||||||
|
} else if (double.class.equals(componentType)) {
|
||||||
|
double[] arr = (double[]) objectToBeMadeIntoVariant;
|
||||||
|
sa = new SafeArray(Variant.VariantDouble, len1);
|
||||||
|
for (int i = 0; i < len1; i++) {
|
||||||
|
sa.setDouble(i, arr[i]);
|
||||||
|
}
|
||||||
|
} else if (long.class.equals(componentType)) {
|
||||||
|
long[] arr = (long[]) objectToBeMadeIntoVariant;
|
||||||
|
sa = new SafeArray(Variant.VariantLongInt, len1);
|
||||||
|
for (int i = 0; i < len1; i++) {
|
||||||
|
sa.setLong(i, arr[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// array of object
|
||||||
|
sa = new SafeArray(Variant.VariantVariant, len1);
|
||||||
|
for (int i = 0; i < len1; i++) {
|
||||||
|
sa.setVariant(i, objectToVariant(Array.get(
|
||||||
|
objectToBeMadeIntoVariant, i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Variant returnVariant = new Variant();
|
||||||
|
populateVariant(returnVariant, sa, false);
|
||||||
|
return returnVariant;
|
||||||
|
} else {
|
||||||
|
// rely on populateVariant to throw an exception if its an
|
||||||
|
// invalid type
|
||||||
|
Variant returnVariant = new Variant();
|
||||||
|
populateVariant(returnVariant, objectToBeMadeIntoVariant, false);
|
||||||
|
return returnVariant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* converts an array of objects into an array of Variants by repeatedly
|
||||||
|
* calling obj2Variant(Object)
|
||||||
|
*
|
||||||
|
* @param arrayOfObjectsToBeConverted
|
||||||
|
* @return Variant[]
|
||||||
|
*/
|
||||||
|
protected static Variant[] objectsToVariants(
|
||||||
|
Object[] arrayOfObjectsToBeConverted) {
|
||||||
|
if (arrayOfObjectsToBeConverted instanceof Variant[]) {
|
||||||
|
// just return the passed in array if it is a Variant array
|
||||||
|
return (Variant[]) arrayOfObjectsToBeConverted;
|
||||||
|
} else {
|
||||||
|
Variant vArg[] = new Variant[arrayOfObjectsToBeConverted.length];
|
||||||
|
for (int i = 0; i < arrayOfObjectsToBeConverted.length; i++) {
|
||||||
|
vArg[i] = objectToVariant(arrayOfObjectsToBeConverted[i]);
|
||||||
|
}
|
||||||
|
return vArg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a JACOB Variant value to a Java object (type conversions).
|
||||||
|
* provided in Sourceforge feature request 959381. A fix was done to handle
|
||||||
|
* byRef bug report 1607878.
|
||||||
|
* <p>
|
||||||
|
* Unlike other toXXX() methods, it does not do a type conversion except for
|
||||||
|
* special data types (it shouldn't do any!)
|
||||||
|
* <p>
|
||||||
|
* Converts Variant.VariantArray types to SafeArrays
|
||||||
|
*
|
||||||
|
* @return Corresponding Java object of the type matching the Variant type.
|
||||||
|
* @throws IllegalStateException
|
||||||
|
* if no underlying windows data structure
|
||||||
|
* @throws NotImplementedException
|
||||||
|
* if unsupported conversion is requested
|
||||||
|
* @throws JacobException
|
||||||
|
* if the calculated result was a JacobObject usually as a
|
||||||
|
* result of error
|
||||||
|
*/
|
||||||
|
protected static Object variantToObject(Variant sourceData) {
|
||||||
|
Object result = null;
|
||||||
|
|
||||||
|
short type = sourceData.getvt(); // variant type
|
||||||
|
|
||||||
|
if ((type & Variant.VariantArray) == Variant.VariantArray) { // array
|
||||||
|
// returned?
|
||||||
|
SafeArray array = null;
|
||||||
|
type = (short) (type - Variant.VariantArray);
|
||||||
|
// From SF Bug 1840487
|
||||||
|
// This did call toSafeArray(false) but that meant
|
||||||
|
// this was the only variantToObject() that didn't have its own
|
||||||
|
// copy of the data so you would end up with weird run time
|
||||||
|
// errors after some GC. So now we just get stupid about it and
|
||||||
|
// always make a copy just like toSafeArray() does.
|
||||||
|
array = sourceData.toSafeArray();
|
||||||
|
result = array;
|
||||||
|
} else { // non-array object returned
|
||||||
|
switch (type) {
|
||||||
|
case Variant.VariantEmpty: // 0
|
||||||
|
case Variant.VariantNull: // 1
|
||||||
|
break;
|
||||||
|
case Variant.VariantShort: // 2
|
||||||
|
result = new Short(sourceData.getShort());
|
||||||
|
break;
|
||||||
|
case Variant.VariantShort | Variant.VariantByref: // 2
|
||||||
|
result = new Short(sourceData.getShortRef());
|
||||||
|
break;
|
||||||
|
case Variant.VariantInt: // 3
|
||||||
|
result = new Integer(sourceData.getInt());
|
||||||
|
break;
|
||||||
|
case Variant.VariantInt | Variant.VariantByref: // 3
|
||||||
|
result = new Integer(sourceData.getIntRef());
|
||||||
|
break;
|
||||||
|
case Variant.VariantFloat: // 4
|
||||||
|
result = new Float(sourceData.getFloat());
|
||||||
|
break;
|
||||||
|
case Variant.VariantFloat | Variant.VariantByref: // 4
|
||||||
|
result = new Float(sourceData.getFloatRef());
|
||||||
|
break;
|
||||||
|
case Variant.VariantDouble: // 5
|
||||||
|
result = new Double(sourceData.getDouble());
|
||||||
|
break;
|
||||||
|
case Variant.VariantDouble | Variant.VariantByref: // 5
|
||||||
|
result = new Double(sourceData.getDoubleRef());
|
||||||
|
break;
|
||||||
|
case Variant.VariantCurrency: // 6
|
||||||
|
result = sourceData.getCurrency();
|
||||||
|
break;
|
||||||
|
case Variant.VariantCurrency | Variant.VariantByref: // 6
|
||||||
|
result = sourceData.getCurrencyRef();
|
||||||
|
break;
|
||||||
|
case Variant.VariantDate: // 7
|
||||||
|
result = sourceData.getJavaDate();
|
||||||
|
break;
|
||||||
|
case Variant.VariantDate | Variant.VariantByref: // 7
|
||||||
|
result = sourceData.getJavaDateRef();
|
||||||
|
break;
|
||||||
|
case Variant.VariantString: // 8
|
||||||
|
result = sourceData.getString();
|
||||||
|
break;
|
||||||
|
case Variant.VariantString | Variant.VariantByref: // 8
|
||||||
|
result = sourceData.getStringRef();
|
||||||
|
break;
|
||||||
|
case Variant.VariantDispatch: // 9
|
||||||
|
result = sourceData.getDispatch();
|
||||||
|
break;
|
||||||
|
case Variant.VariantDispatch | Variant.VariantByref: // 9
|
||||||
|
result = sourceData.getDispatchRef(); // Can dispatches even
|
||||||
|
// be byRef?
|
||||||
|
break;
|
||||||
|
case Variant.VariantError: // 10
|
||||||
|
result = new NotImplementedException(
|
||||||
|
"toJavaObject() Not implemented for VariantError");
|
||||||
|
break;
|
||||||
|
case Variant.VariantBoolean: // 11
|
||||||
|
result = new Boolean(sourceData.getBoolean());
|
||||||
|
break;
|
||||||
|
case Variant.VariantBoolean | Variant.VariantByref: // 11
|
||||||
|
result = new Boolean(sourceData.getBooleanRef());
|
||||||
|
break;
|
||||||
|
case Variant.VariantVariant: // 12 they are always by ref
|
||||||
|
result = new NotImplementedException(
|
||||||
|
"toJavaObject() Not implemented for VariantVariant without ByRef");
|
||||||
|
break;
|
||||||
|
case Variant.VariantVariant | Variant.VariantByref: // 12
|
||||||
|
result = sourceData.getVariant();
|
||||||
|
break;
|
||||||
|
case Variant.VariantObject: // 13
|
||||||
|
result = new NotImplementedException(
|
||||||
|
"toJavaObject() Not implemented for VariantObject");
|
||||||
|
break;
|
||||||
|
case Variant.VariantDecimal: // 14
|
||||||
|
result = sourceData.getDecimal();
|
||||||
|
break;
|
||||||
|
case Variant.VariantDecimal | Variant.VariantByref: // 14
|
||||||
|
result = sourceData.getDecimalRef();
|
||||||
|
break;
|
||||||
|
case Variant.VariantByte: // 17
|
||||||
|
result = new Byte(sourceData.getByte());
|
||||||
|
break;
|
||||||
|
case Variant.VariantByte | Variant.VariantByref: // 17
|
||||||
|
result = new Byte(sourceData.getByteRef());
|
||||||
|
break;
|
||||||
|
case Variant.VariantLongInt: // 20
|
||||||
|
result = new Long(sourceData.getLong());
|
||||||
|
break;
|
||||||
|
case Variant.VariantLongInt | Variant.VariantByref: // 20
|
||||||
|
result = new Long(sourceData.getLongRef());
|
||||||
|
break;
|
||||||
|
case Variant.VariantTypeMask: // 4095
|
||||||
|
result = new NotImplementedException(
|
||||||
|
"toJavaObject() Not implemented for VariantBstrBlob/VariantTypeMask");
|
||||||
|
break;
|
||||||
|
case Variant.VariantArray: // 8192
|
||||||
|
result = new NotImplementedException(
|
||||||
|
"toJavaObject() Not implemented for VariantArray");
|
||||||
|
break;
|
||||||
|
case Variant.VariantByref: // 16384
|
||||||
|
result = new NotImplementedException(
|
||||||
|
"toJavaObject() Not implemented for VariantByref");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = new NotImplementedException("Unknown return type: "
|
||||||
|
+ type);
|
||||||
|
// there was a "return result" here that caused defect 1602118
|
||||||
|
// so it was removed
|
||||||
|
break;
|
||||||
|
}// switch (type)
|
||||||
|
|
||||||
|
if (result instanceof JacobException) {
|
||||||
|
throw (JacobException) result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}// toJava()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that we have a scale 0 <= x <= 28 and now more than 96 bits of
|
||||||
|
* data. The roundToMSDecimal method will attempt to adjust a BigDecimal to
|
||||||
|
* pass this set of tests
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if out of bounds
|
||||||
|
*/
|
||||||
|
protected static void validateDecimalScaleAndBits(BigDecimal in) {
|
||||||
|
BigInteger allWordBigInt = in.unscaledValue();
|
||||||
|
if (in.scale() > 28) {
|
||||||
|
// should this cast to a string and call putStringRef()?
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"VT_DECIMAL only supports a maximum scale of 28 and the passed"
|
||||||
|
+ " in value has a scale of " + in.scale());
|
||||||
|
} else if (in.scale() < 0) {
|
||||||
|
// should this cast to a string and call putStringRef()?
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"VT_DECIMAL only supports a minimum scale of 0 and the passed"
|
||||||
|
+ " in value has a scale of " + in.scale());
|
||||||
|
} else if (allWordBigInt.bitLength() > 12 * 8) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"VT_DECIMAL supports a maximum of "
|
||||||
|
+ 12
|
||||||
|
* 8
|
||||||
|
+ " bits not counting scale and the number passed in has "
|
||||||
|
+ allWordBigInt.bitLength());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// no bounds problem to be handled
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Largest possible number with scale set to 0
|
||||||
|
*/
|
||||||
|
private static final BigDecimal LARGEST_DECIMAL = new BigDecimal(
|
||||||
|
new BigInteger("ffffffffffffffffffffffff", 16));
|
||||||
|
/**
|
||||||
|
* Smallest possible number with scale set to 0. MS doesn't support negative
|
||||||
|
* scales like BigDecimal.
|
||||||
|
*/
|
||||||
|
private static final BigDecimal SMALLEST_DECIMAL = new BigDecimal(
|
||||||
|
new BigInteger("ffffffffffffffffffffffff", 16).negate());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does any validation that couldn't have been fixed by rounding or scale
|
||||||
|
* modification.
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* The BigDecimal to be validated
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if the number is too large or too small or null
|
||||||
|
*/
|
||||||
|
protected static void validateDecimalMinMax(BigDecimal in) {
|
||||||
|
if (in == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"null is not a supported Decimal value.");
|
||||||
|
} else if (LARGEST_DECIMAL.compareTo(in) < 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Value too large for VT_DECIMAL data type:" + in.toString()
|
||||||
|
+ " integer: " + in.toBigInteger().toString(16)
|
||||||
|
+ " scale: " + in.scale());
|
||||||
|
} else if (SMALLEST_DECIMAL.compareTo(in) > 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Value too small for VT_DECIMAL data type:" + in.toString()
|
||||||
|
+ " integer: " + in.toBigInteger().toString(16)
|
||||||
|
+ " scale: " + in.scale());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rounds the scale and bit length so that it will pass
|
||||||
|
* validateDecimalScaleBits(). Developers should call this method if they
|
||||||
|
* really want MS Decimal and don't want to lose precision.
|
||||||
|
* <p>
|
||||||
|
* Changing the scale on a number that can fit in an MS Decimal can change
|
||||||
|
* the number's representation enough that it will round to a number too
|
||||||
|
* large to be represented by an MS VT_DECIMAL
|
||||||
|
*
|
||||||
|
* @param sourceDecimal
|
||||||
|
* @return BigDecimal a new big decimal that was rounded to fit in an MS
|
||||||
|
* VT_DECIMAL
|
||||||
|
*/
|
||||||
|
public static BigDecimal roundToMSDecimal(BigDecimal sourceDecimal) {
|
||||||
|
BigInteger sourceDecimalIntComponent = sourceDecimal.unscaledValue();
|
||||||
|
BigDecimal destinationDecimal = new BigDecimal(
|
||||||
|
sourceDecimalIntComponent, sourceDecimal.scale());
|
||||||
|
int roundingModel = BigDecimal.ROUND_HALF_UP;
|
||||||
|
validateDecimalMinMax(destinationDecimal);
|
||||||
|
// First limit the number of digits and then the precision.
|
||||||
|
// Try and round to 29 digits because we can sometimes do that
|
||||||
|
BigInteger allWordBigInt;
|
||||||
|
allWordBigInt = destinationDecimal.unscaledValue();
|
||||||
|
if (allWordBigInt.bitLength() > 96) {
|
||||||
|
destinationDecimal = destinationDecimal.round(new MathContext(29));
|
||||||
|
// see if 29 digits uses more than 96 bits
|
||||||
|
if (allWordBigInt.bitLength() > 96) {
|
||||||
|
// Dang. It was over 97 bits so shorten it one more digit to
|
||||||
|
// stay <= 96 bits
|
||||||
|
destinationDecimal = destinationDecimal.round(new MathContext(
|
||||||
|
28));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// the bit manipulations above may change the scale so do it afterwards
|
||||||
|
// round the scale to the max MS can support
|
||||||
|
if (destinationDecimal.scale() > 28) {
|
||||||
|
destinationDecimal = destinationDecimal.setScale(28, roundingModel);
|
||||||
|
}
|
||||||
|
if (destinationDecimal.scale() < 0) {
|
||||||
|
destinationDecimal = destinationDecimal.setScale(0, roundingModel);
|
||||||
|
}
|
||||||
|
return destinationDecimal;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
java/src/com/jacob/com/VariantViaEvent.java
Normal file
34
java/src/com/jacob/com/VariantViaEvent.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a public class to variant that is used to track which variant objects are
|
||||||
|
* created by event callbacks This is solely used for that purpose.
|
||||||
|
*/
|
||||||
|
public class VariantViaEvent extends Variant {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard constructor used by JNI event handling layer
|
||||||
|
*/
|
||||||
|
public VariantViaEvent() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
47
java/src/com/jacob/com/WrongThreadException.java
Normal file
47
java/src/com/jacob/com/WrongThreadException.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||||
|
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||||
|
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.jacob.com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* thrown in util.cpp
|
||||||
|
*/
|
||||||
|
public class WrongThreadException extends JacobException {
|
||||||
|
/**
|
||||||
|
* identifier generated by Eclipse
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 6308780364980228692L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* standard 0 arg constructor with no message
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public WrongThreadException() {
|
||||||
|
super("No Message Provided.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* standard constructor with a string message
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
public WrongThreadException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,9 +5,11 @@ import java.util.Queue;
|
|||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
import pm.application.Application;
|
import pm.application.Application;
|
||||||
|
import pm.application.iTunes.iTunesApplicatie;
|
||||||
import pm.application.voorbeeld.VoorbeeldApplication;
|
import pm.application.voorbeeld.VoorbeeldApplication;
|
||||||
import pm.device.Device;
|
import pm.device.Device;
|
||||||
import pm.device.javainput.extreme3d.Extreme3DDevice;
|
import pm.device.javainput.extreme3d.Extreme3DDevice;
|
||||||
|
import pm.device.javainput.rumblepad.RumblepadDevice;
|
||||||
import pm.device.jintellitype.JIntellitypeDevice;
|
import pm.device.jintellitype.JIntellitypeDevice;
|
||||||
import pm.device.wiimote.WiimoteDevice;
|
import pm.device.wiimote.WiimoteDevice;
|
||||||
import pm.exception.ActionException;
|
import pm.exception.ActionException;
|
||||||
@@ -50,12 +52,13 @@ public class Main {
|
|||||||
|
|
||||||
public void start() throws Exception {
|
public void start() throws Exception {
|
||||||
//add(new ExampleDevice());
|
//add(new ExampleDevice());
|
||||||
//add(new RumblepadDevice());
|
add(new RumblepadDevice());
|
||||||
add(new Extreme3DDevice());
|
//add(new Extreme3DDevice());
|
||||||
add(new JIntellitypeDevice());
|
add(new JIntellitypeDevice());
|
||||||
add(new WiimoteDevice());
|
//add(new WiimoteDevice());
|
||||||
|
|
||||||
Application application = new VoorbeeldApplication();
|
Application application = new VoorbeeldApplication();
|
||||||
|
application = new iTunesApplicatie();
|
||||||
add(application);
|
add(application);
|
||||||
|
|
||||||
for (Device device : deviceList) {
|
for (Device device : deviceList) {
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import com.jacob.activeX.ActiveXComponent;
|
|||||||
import com.jacob.com.ComThread;
|
import com.jacob.com.ComThread;
|
||||||
import com.jacob.com.Dispatch;
|
import com.jacob.com.Dispatch;
|
||||||
|
|
||||||
public class iTunes extends Application{
|
public class iTunesApplicatie extends Application{
|
||||||
|
|
||||||
Dispatch iTunesController;
|
Dispatch iTunesController;
|
||||||
|
|
||||||
public iTunes() {
|
public iTunesApplicatie() {
|
||||||
connect();
|
connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ public class iTunes extends Application{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String argv[]) throws Exception {
|
public static void main(String argv[]) throws Exception {
|
||||||
new iTunes();
|
new iTunesApplicatie();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,12 +8,9 @@ import de.hardcode.jxinput.event.JXInputDirectionalEvent;
|
|||||||
|
|
||||||
import pm.Button;
|
import pm.Button;
|
||||||
import pm.device.Device;
|
import pm.device.Device;
|
||||||
import pm.device.javainput.extreme3d.Extreme3DButton;
|
|
||||||
import pm.device.javainput.extreme3d.Extreme3DDirection;
|
|
||||||
import pm.exception.DeviceException;
|
import pm.exception.DeviceException;
|
||||||
import pm.exception.EventException;
|
import pm.exception.EventException;
|
||||||
import pm.exception.device.JavaInputDeviceNotFoundException;
|
import pm.exception.device.JavaInputDeviceNotFoundException;
|
||||||
import pm.exception.event.UnknownDirectionException;
|
|
||||||
import pm.macro.event.Press;
|
import pm.macro.event.Press;
|
||||||
import pm.macro.event.Release;
|
import pm.macro.event.Release;
|
||||||
|
|
||||||
@@ -50,7 +47,7 @@ public abstract class JavaInputDevice extends Device {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void processEvent(JXInputButtonEvent event) throws EventException {
|
public void processEvent(JXInputButtonEvent event) throws EventException {
|
||||||
Button button = Extreme3DButton.create(event);
|
Button button = getButton(event);
|
||||||
if (event.getButton().getState()) {
|
if (event.getButton().getState()) {
|
||||||
System.out.println("Press: " + button);
|
System.out.println("Press: " + button);
|
||||||
add(new Press(button));
|
add(new Press(button));
|
||||||
@@ -60,8 +57,8 @@ public abstract class JavaInputDevice extends Device {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processEvent(JXInputDirectionalEvent event) throws UnknownDirectionException {
|
public void processEvent(JXInputDirectionalEvent event) throws EventException {
|
||||||
Button button = Extreme3DDirection.create(event);
|
Button button = getButton(event);
|
||||||
if (event.getDirectional().isCentered()) {
|
if (event.getDirectional().isCentered()) {
|
||||||
if (previousDirectionalButton != null) {
|
if (previousDirectionalButton != null) {
|
||||||
System.out.println("Release: " + previousDirectionalButton);
|
System.out.println("Release: " + previousDirectionalButton);
|
||||||
@@ -73,4 +70,7 @@ public abstract class JavaInputDevice extends Device {
|
|||||||
previousDirectionalButton = button;
|
previousDirectionalButton = button;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract Button getButton(JXInputButtonEvent event) throws EventException;
|
||||||
|
protected abstract Button getButton(JXInputDirectionalEvent event) throws EventException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
package pm.device.javainput.extreme3d;
|
package pm.device.javainput.extreme3d;
|
||||||
|
|
||||||
|
import de.hardcode.jxinput.event.JXInputButtonEvent;
|
||||||
|
import de.hardcode.jxinput.event.JXInputDirectionalEvent;
|
||||||
import pm.Action;
|
import pm.Action;
|
||||||
|
import pm.Button;
|
||||||
import pm.Macro;
|
import pm.Macro;
|
||||||
import pm.Target;
|
import pm.Target;
|
||||||
import pm.device.javainput.JavaInputDevice;
|
import pm.device.javainput.JavaInputDevice;
|
||||||
import pm.exception.DeviceException;
|
import pm.exception.DeviceException;
|
||||||
import pm.exception.MacroException;
|
import pm.exception.MacroException;
|
||||||
|
import pm.exception.event.UnknownButtonException;
|
||||||
|
import pm.exception.event.UnknownDirectionException;
|
||||||
import pm.macro.event.Hold;
|
import pm.macro.event.Hold;
|
||||||
import pm.macro.event.Press;
|
import pm.macro.event.Press;
|
||||||
import pm.macro.event.Release;
|
import pm.macro.event.Release;
|
||||||
@@ -34,4 +39,12 @@ public class Extreme3DDevice extends JavaInputDevice {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Button getButton(JXInputButtonEvent event) throws UnknownButtonException {
|
||||||
|
return Extreme3DButton.create(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Button getButton(JXInputDirectionalEvent event) throws UnknownDirectionException {
|
||||||
|
return Extreme3DDirection.create(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
package pm.device.javainput.rumblepad;
|
package pm.device.javainput.rumblepad;
|
||||||
|
|
||||||
|
import de.hardcode.jxinput.event.JXInputButtonEvent;
|
||||||
|
import de.hardcode.jxinput.event.JXInputDirectionalEvent;
|
||||||
import pm.Action;
|
import pm.Action;
|
||||||
|
import pm.Button;
|
||||||
|
import pm.Macro;
|
||||||
import pm.Target;
|
import pm.Target;
|
||||||
import pm.device.javainput.JavaInputDevice;
|
import pm.device.javainput.JavaInputDevice;
|
||||||
import pm.exception.DeviceException;
|
import pm.exception.DeviceException;
|
||||||
import pm.exception.MacroException;
|
import pm.exception.MacroException;
|
||||||
|
import pm.exception.event.UnknownButtonException;
|
||||||
|
import pm.exception.event.UnknownDirectionException;
|
||||||
import pm.macro.event.Press;
|
import pm.macro.event.Press;
|
||||||
|
|
||||||
public class RumblepadDevice extends JavaInputDevice {
|
public class RumblepadDevice extends JavaInputDevice {
|
||||||
@@ -18,7 +24,7 @@ public class RumblepadDevice extends JavaInputDevice {
|
|||||||
public void start() {
|
public void start() {
|
||||||
super.start();
|
super.start();
|
||||||
try {
|
try {
|
||||||
/*add(
|
add(
|
||||||
new Press(RumblepadButton.ONE),
|
new Press(RumblepadButton.ONE),
|
||||||
Action.PLAY.setTarget(Target.APPLICATION));
|
Action.PLAY.setTarget(Target.APPLICATION));
|
||||||
add(
|
add(
|
||||||
@@ -26,12 +32,23 @@ public class RumblepadDevice extends JavaInputDevice {
|
|||||||
Action.PAUSE.setTarget(Target.APPLICATION));
|
Action.PAUSE.setTarget(Target.APPLICATION));
|
||||||
add(
|
add(
|
||||||
new Press(RumblepadButton.THREE),
|
new Press(RumblepadButton.THREE),
|
||||||
Action.RESUME.setTarget(Target.APPLICATION));*/
|
Action.RESUME.setTarget(Target.APPLICATION));
|
||||||
add(
|
add(
|
||||||
new Press(RumblepadButton.FOUR),
|
new Macro(
|
||||||
|
new Press(RumblepadButton.ONE)
|
||||||
|
),
|
||||||
Action.EXIT.setTarget(Target.MAIN));
|
Action.EXIT.setTarget(Target.MAIN));
|
||||||
} catch (MacroException e) {
|
} catch (MacroException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Button getButton(JXInputButtonEvent event) throws UnknownButtonException {
|
||||||
|
return RumblepadButton.create(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Button getButton(JXInputDirectionalEvent event) throws UnknownDirectionException {
|
||||||
|
return RumblepadDirection.create(event);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,7 @@ public class JIntellitypeDevice extends Device implements HotkeyListener, Intell
|
|||||||
jit.addIntellitypeListener(this);
|
jit.addIntellitypeListener(this);
|
||||||
try {
|
try {
|
||||||
add(
|
add(
|
||||||
new Macro(
|
new Hotkey(HotkeyButton.CTRL, 'x'),
|
||||||
new Hotkey('r'),
|
|
||||||
new Hotkey('i'),
|
|
||||||
new Hotkey('k')),
|
|
||||||
Action.EXIT.setTarget(Target.MAIN));
|
Action.EXIT.setTarget(Target.MAIN));
|
||||||
add(
|
add(
|
||||||
new Press(CommandButton.VOLUME_UP),
|
new Press(CommandButton.VOLUME_UP),
|
||||||
|
|||||||
@@ -14,6 +14,6 @@ public abstract class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(Event event) {
|
public boolean equals(Event event) {
|
||||||
return event.getClass().equals(getClass()) && event.getButton().equals(button); // Todo: controleren of equals goed werkt bij buttons van verschillende typen
|
return event.getClass().equals(getClass()) && event.getButton().equals(button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user