merged R-1_9 release tag against the root-B-1_9
This commit is contained in:
11
.cvsignore
Normal file
11
.cvsignore
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
jacob.dll
|
||||||
|
jacob.jar
|
||||||
|
jacobdll.jar
|
||||||
|
*.zip
|
||||||
|
RELEASE.txt
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
compilation_tools.properties
|
||||||
|
version.properties
|
||||||
|
release
|
||||||
|
|
||||||
28
README.TXT
28
README.TXT
@@ -1,28 +0,0 @@
|
|||||||
For documentation see: http://users.rcn.com/danadler/jacob/
|
|
||||||
|
|
||||||
The java code is in com\jacob\*.
|
|
||||||
|
|
||||||
The C++ code is in .\jni.
|
|
||||||
|
|
||||||
To build, run:
|
|
||||||
|
|
||||||
nmake -f makefile
|
|
||||||
|
|
||||||
That will first compile the JAVA files and build the JAR file, and
|
|
||||||
then compile the C++ code and build the DLL.
|
|
||||||
|
|
||||||
Building the jni:
|
|
||||||
|
|
||||||
The following are hardcoded into the makefile, so you may have to
|
|
||||||
change it. I developed this with the C++ compiler and ATL version
|
|
||||||
that ship with VC++ 6.0, so I'm not sure if different versions will
|
|
||||||
work.
|
|
||||||
|
|
||||||
I have compiled this against JDK 1.1.6 and 1.2.2 as well as Microsoft
|
|
||||||
SDK for Java 3.2 as the JDK setting.
|
|
||||||
|
|
||||||
DEST_DIR is a destination directory into which to copy the final DLL.
|
|
||||||
|
|
||||||
JDK = d:\j2sdk1.4.2_06
|
|
||||||
DEST_DIR = d:\jacob
|
|
||||||
MSDEVDIR = d:\apps\\"Microsoft Visual Studio"\VC98
|
|
||||||
114
WhatsNew.html
114
WhatsNew.html
@@ -1,114 +0,0 @@
|
|||||||
<h1>What's New in JACOB 1.8</H1>
|
|
||||||
<ul>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>Move To SourceForge</b>
|
|
||||||
The project is not housed at
|
|
||||||
<a href="http://sourceforge.net/projects/jacob-project/">Sourceforge.net</a>.
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>Licensing Change</b>
|
|
||||||
All limitations on commercial use of JACOB have been removed and it
|
|
||||||
is now being developed under a BSD license at
|
|
||||||
<a href="http://sourceforge.net/projects/jacob-project/">Sourceforge.net</a>.
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>Compiled with Java 1.4.2</b>
|
|
||||||
Version 1.8 was compiled with JSEE 1.4.2 and fixes the compilation bug
|
|
||||||
that was remnant of compilation with JDK 1.1.
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>Baseline For Change</b>
|
|
||||||
This version is the baseline for the first CVS checkin and we encourage
|
|
||||||
people to start contributing to the project with this version.
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<h1>What's New in JACOB 1.7</H1>
|
|
||||||
<ul>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>Explicit COM Threading Model Support:</b>
|
|
||||||
See a detailed discussion of
|
|
||||||
<a href="JacobThreading.html">COM Apartments in JACOB</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>New COM Object Lifetime model:</b>
|
|
||||||
See a detailed discussion of
|
|
||||||
<a href="JacobComLifetime.html">COM Object Lifetime in JACOB</a>.
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>Improved Event Handling:</b>
|
|
||||||
Thanks to code contributed by
|
|
||||||
<a href="mailto:n.o.bouvin@daimi.au.dk">
|
|
||||||
Niels Olof Bouvin</a>
|
|
||||||
and <a href="mailto:jehoej@daimi.au.dk">Henning Jae</a> JACOB 1.7 can
|
|
||||||
read the type information of a Connection Point interface by looking
|
|
||||||
it up in the registry. This makes it possible to use events with IE as
|
|
||||||
well as office products.
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>Improved Dispatch:</b>
|
|
||||||
Error messages from Invoke failures are now printed out as well as
|
|
||||||
allowing the passing in of arguments to a Get method.
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>EnumVariant Implementation:</b>
|
|
||||||
Makes it easier to iterate over COM collections. Thanks to code
|
|
||||||
contributed by
|
|
||||||
<a href="mailto:Thomas.Hallgren@eoncompany.com">Thomas Hallgren</a>.
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>SafeArray leaks:</b>
|
|
||||||
SafeArrays were not being properly freed prior to version 1.7, many
|
|
||||||
other memory leaks were fixed as well.
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>Visual Studio Project:</b>
|
|
||||||
For those who want to debug: vstudio/jacob. At the moment all the
|
|
||||||
native code is replicated there from the jni directory...
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
<H1>Related Links</H1>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
The JACOB mailing list is hosted at yahoo groups:
|
|
||||||
<a href="http://groups.yahoo.com/group/jacob-project">
|
|
||||||
http://groups.yahoo.com/group/jacob-project</a>.
|
|
||||||
<b>This is the preferred way to get support for JACOB</b>. It also
|
|
||||||
includes an extensive archive. If you are doing any development with
|
|
||||||
JACOB, please join the list.
|
|
||||||
<li>
|
|
||||||
Massimiliano Bigatti has developed
|
|
||||||
<a href="http://www.bigatti.it/projects/jacobgen/">
|
|
||||||
Jacobgen - a generator that automatically creates JACOB code from
|
|
||||||
Type Libraries</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Steven Lewis is developing a version of Java2Com that supports JACOB
|
|
||||||
code generation. See:
|
|
||||||
<a href="http://www.lordjoe.com/Java2Com/index.html">
|
|
||||||
http://www.lordjoe.com/Java2Com/index.html</a>.
|
|
||||||
<li>
|
|
||||||
To find documentation on the com.ms.com package, go to:
|
|
||||||
<a href="http://www.microsoft.com/java/download/dl_sdk40.htm">
|
|
||||||
http://www.microsoft.com/java/download/dl_sdk40.htm</a>
|
|
||||||
and at the bottom of the page is a link that says:
|
|
||||||
Microsoft SDK for Java 4.0 Documentation Only. You should download
|
|
||||||
that file and install it. Then, view sdkdocs.chm and look for
|
|
||||||
"Microsoft Packages Reference". Hopefully, the next release of
|
|
||||||
JACOB will include full javadoc (volunteers?)...
|
|
||||||
</li>
|
|
||||||
267
build.xml
Normal file
267
build.xml
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- ======================================================================
|
||||||
|
Feb 4, 2005 1:23:05 PM
|
||||||
|
|
||||||
|
Ant build file for JACOB.
|
||||||
|
Tested on Eclipse 3.0.0 and Ant 1.6.1, with MS Visual C++ 6.0
|
||||||
|
|
||||||
|
Eclipse users are pretty lucky. This works with the version of ANT
|
||||||
|
that comes with Eclipse 3.0.1 (maybe 3.0.0). The whole project
|
||||||
|
can be built inside eclipse.
|
||||||
|
|
||||||
|
If you do not have a C++ environment check out the following sites
|
||||||
|
http://msdn.microsoft.com/visualc/vctoolkit2003/
|
||||||
|
http://www.eclipse.org/cdt/
|
||||||
|
http://eclipsewiki.editme.com/InstallingCDTWithMSVisualC
|
||||||
|
|
||||||
|
====================================================================== -->
|
||||||
|
<project name="jacob" default="default" basedir=".">
|
||||||
|
<property file="compilation_tools.properties" />
|
||||||
|
<!-- =v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=
|
||||||
|
YOU MUST define a file named compilation_tools.properties
|
||||||
|
and looking like this:
|
||||||
|
|
||||||
|
JDK=D:/J2SDK-1_4_2
|
||||||
|
MSDEVDIR=C:/Program Files/Microsoft Visual Studio/VC98
|
||||||
|
version=1.9
|
||||||
|
|
||||||
|
DO NOT check this file into source control as the values are specific
|
||||||
|
to YOUR environment.
|
||||||
|
|
||||||
|
the version.properties file is now completely autogenerated
|
||||||
|
|
||||||
|
=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^ -->
|
||||||
|
|
||||||
|
<property name="application.title" value="JACOB : Java COM Bridge" />
|
||||||
|
<property name="application.vendor" value="http://jacob-project.sourceforge.net, created by Dan Adler (http://danadler.com)" />
|
||||||
|
<property name="install.dir" value="${basedir}/release" />
|
||||||
|
|
||||||
|
<property name="jacob_java.src" value="${basedir}/src" />
|
||||||
|
<property name="jacob_java.samples" value="${basedir}/samples" />
|
||||||
|
<property name="jacob_java.unittest" value="${basedir}/unittest" />
|
||||||
|
<property name="jacob_java.bin" value="${install.dir}" />
|
||||||
|
<property name="jacob_cpp.src" value="${basedir}/jni" />
|
||||||
|
<property name="jacob_cpp.bin" value="${install.dir}/jni" />
|
||||||
|
|
||||||
|
<property name="jacob.jar" value="${install.dir}/jacob.jar" />
|
||||||
|
<property name="jacob.dll" value="${install.dir}/jacob.dll" />
|
||||||
|
|
||||||
|
<property name="compiler" value="${MSDEVDIR}\bin\cl.exe" />
|
||||||
|
<property name="linker" value="${MSDEVDIR}\bin\link.exe" />
|
||||||
|
|
||||||
|
<!-- =================================
|
||||||
|
target: default
|
||||||
|
================================= -->
|
||||||
|
<target name="default" depends="createDirectoryStructure,jacob_java_jar_bin,jacob_c_dll">
|
||||||
|
|
||||||
|
<echo message="Jacob ${version} build ${build.iteration} : finished on ${build.date}" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- ======================================================================
|
||||||
|
Writes out a version file to be included in the jar
|
||||||
|
================================================================== -->
|
||||||
|
<target name="IncrementBuildNumber">
|
||||||
|
<propertyfile file="version.properties">
|
||||||
|
<entry key="version" type="string" value="${version}" />
|
||||||
|
<entry key="build.iteration" type="int" operation="+" value="1" pattern="00" />
|
||||||
|
<entry key="build.date" type="date" value="now" operation="=" pattern="dd-MMMM-yyyy HH:mm:ss" />
|
||||||
|
</propertyfile>
|
||||||
|
<property file="version.properties" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- ======================================================================
|
||||||
|
Create the necessary directory structure (does nothing if it
|
||||||
|
already there)
|
||||||
|
================================================================== -->
|
||||||
|
<target name="createDirectoryStructure">
|
||||||
|
<mkdir dir="${jacob_java.bin}"/>
|
||||||
|
<mkdir dir="${jacob_cpp.bin}"/>
|
||||||
|
<mkdir dir="${install.dir}"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- ======================================================================
|
||||||
|
Compare the date/time of the jacob JAR against that
|
||||||
|
of the jacob java source
|
||||||
|
================================================================== -->
|
||||||
|
<target name="jacob_java_jar_check">
|
||||||
|
<uptodate property="jarUpToDate" targetfile="${jacob.jar}">
|
||||||
|
<srcfiles dir="${jacob_java.src}">
|
||||||
|
<include name="com/**/*.java" />
|
||||||
|
</srcfiles>
|
||||||
|
<!-- Check the build file itself as well -->
|
||||||
|
<srcfiles file="${basedir}/build.xml" />
|
||||||
|
</uptodate>
|
||||||
|
<echo message="jacob_java_jar_check result: ${jarUpToDate}" />
|
||||||
|
</target>
|
||||||
|
<!-- ======================================================================
|
||||||
|
Compile the java files
|
||||||
|
Relies on ant recognizing when a file needs to be compiled
|
||||||
|
================================================================== -->
|
||||||
|
<target name="jacob_java_compile" depends="createDirectoryStructure,IncrementBuildNumber">
|
||||||
|
<echo>Building java classes...</echo>
|
||||||
|
<javac srcdir="${jacob_java.src}"
|
||||||
|
destdir="${jacob_java.bin}"
|
||||||
|
listfiles="true" debug="on" fork="yes" />
|
||||||
|
<echo>Building java sample classes...</echo>
|
||||||
|
<javac srcdir="${jacob_java.samples}"
|
||||||
|
destdir="${jacob_java.bin}"
|
||||||
|
excludes="com/jacob/samples/servlet/**/*.java"
|
||||||
|
listfiles="true" debug="on" fork="yes" />
|
||||||
|
<echo>Building java test classes...</echo>
|
||||||
|
<javac srcdir="${jacob_java.unittest}"
|
||||||
|
destdir="${jacob_java.bin}"
|
||||||
|
listfiles="true" debug="on" fork="yes" />
|
||||||
|
</target>
|
||||||
|
<!-- ======================================================================
|
||||||
|
Package the classes into a JAR.
|
||||||
|
Put version.propertes into the jar file so getJacobVersion() can find it
|
||||||
|
================================================================== -->
|
||||||
|
<target name="jacob_java_jar_bin" depends="createDirectoryStructure,jacob_java_compile,jacob_java_jar_check,IncrementBuildNumber" unless="jarUpToDate">
|
||||||
|
<echo>Removing old jars</echo>
|
||||||
|
<delete file="${jacob.jar}" />
|
||||||
|
<echo>Packaging java classes...</echo>
|
||||||
|
<jar destfile="${jacob.jar}" basedir="${jacob_java.bin}" update="false">
|
||||||
|
<exclude name="**/CVS" />
|
||||||
|
<exclude name="com/**/*Test.class"/>
|
||||||
|
<exclude name="com/jacob/samples/**"/>
|
||||||
|
<include name="com/**/*.class" />
|
||||||
|
<include name="version.properties" />
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Built-By" value="${user.name}" />
|
||||||
|
<section name="com.jacob">
|
||||||
|
<attribute name="Specification-Title" value="${application.title}" />
|
||||||
|
<attribute name="Specification-Vendor" value="${application.vendor}" />
|
||||||
|
<attribute name="Implementation-Title" value="${application.title} Java libraries" />
|
||||||
|
<attribute name="Implementation-Version" value="${version} build ${build.iteration} on ${build.date}" />
|
||||||
|
</section>
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
<!-- ======================================================================
|
||||||
|
Compare the date/time of the jacob DLL against that
|
||||||
|
of the jacob cpp source
|
||||||
|
================================================================== -->
|
||||||
|
<target name="jacob_c_check">
|
||||||
|
<uptodate property="dllUpToDate" targetfile="${jacob.dll}">
|
||||||
|
<srcfiles dir="${jacob_cpp.src}">
|
||||||
|
<include name="*.cpp" />
|
||||||
|
<include name="*.h" />
|
||||||
|
</srcfiles>
|
||||||
|
<!-- Check the build file itself as well -->
|
||||||
|
<srcfiles file="${basedir}/build.xml" />
|
||||||
|
</uptodate>
|
||||||
|
<echo message="jacob_c_check result: ${dllUpToDate}" />
|
||||||
|
</target>
|
||||||
|
<!-- ======================================================================
|
||||||
|
Compile the c source files.
|
||||||
|
================================================================== -->
|
||||||
|
<target name="jacob_c_compile" depends="createDirectoryStructure,jacob_c_check,IncrementBuildNumber" unless="dllUpToDate">
|
||||||
|
<echo>Clean up the target folders and file, for safety</echo>
|
||||||
|
<delete file="${jacob_cpp.bin}/**/*.*" />
|
||||||
|
<echo>Compiling C++ classes</echo>
|
||||||
|
<apply executable="${compiler}" dir="${jacob_cpp.bin}" parallel="false" verbose="true" failonerror="true">
|
||||||
|
<arg value="-c" />
|
||||||
|
<arg value="/nologo" />
|
||||||
|
<!-- optimize build for speed. (is this VC specific? -->
|
||||||
|
<arg value="/O2" />
|
||||||
|
<arg value="-I" />
|
||||||
|
<arg value="${JDK}\include" />
|
||||||
|
<arg value="-I" />
|
||||||
|
<arg value="${JDK}\include\win32" />
|
||||||
|
<arg value="-I" />
|
||||||
|
<arg value="${MSDEVDIR}\Include" />
|
||||||
|
<arg value="-I" />
|
||||||
|
<arg value="${MSDEVDIR}\ATL\Include" />
|
||||||
|
<fileset dir="${jacob_cpp.src}">
|
||||||
|
<include name="*.cpp" />
|
||||||
|
</fileset>
|
||||||
|
</apply>
|
||||||
|
</target>
|
||||||
|
<!-- ======================================================================
|
||||||
|
Link the obj files into a DLL.
|
||||||
|
================================================================== -->
|
||||||
|
<target name="jacob_c_dll" depends="createDirectoryStructure,jacob_c_check,jacob_c_compile" unless="dllUpToDate">
|
||||||
|
<echo>Clean up the target folders and file, for safety</echo>
|
||||||
|
<delete file="${jacob.dll}" />
|
||||||
|
<echo>Creating jacob.dll</echo>
|
||||||
|
<apply executable="${linker}" dir="${jacob_cpp.bin}" parallel="true" verbose="true" failonerror="true">
|
||||||
|
<arg value="/nologo" />
|
||||||
|
<arg value="/dll" />
|
||||||
|
<arg value="/version:${version}" />
|
||||||
|
<arg value="/out:${jacob.dll}" />
|
||||||
|
<arg value="/libpath:${MSDEVDIR}/lib" />
|
||||||
|
<srcfile />
|
||||||
|
<arg value="${JDK}\lib\jvm.lib" />
|
||||||
|
<arg value="oleaut32.lib" />
|
||||||
|
<arg value="ole32.lib" />
|
||||||
|
<arg value="uuid.lib" />
|
||||||
|
<arg value="kernel32.lib" />
|
||||||
|
<arg value="shell32.lib" />
|
||||||
|
<arg value="user32.lib" />
|
||||||
|
<fileset dir="${jacob_cpp.bin}">
|
||||||
|
<include name="*.obj" />
|
||||||
|
</fileset>
|
||||||
|
</apply>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- ======================================================================
|
||||||
|
Use this target to create javadoc from com.jacob.*
|
||||||
|
================================================================== -->
|
||||||
|
<target name="javadoc">
|
||||||
|
<defaultexcludes add="**/*Test*"/>
|
||||||
|
<javadoc
|
||||||
|
packagenames="com.jacob/**"
|
||||||
|
sourcepath="${jacob_java.src}"
|
||||||
|
destdir="${jacob_java.bin}/docs/api"
|
||||||
|
author="true"
|
||||||
|
version="true"
|
||||||
|
use="true"
|
||||||
|
windowtitle="Jacob API Docs">
|
||||||
|
|
||||||
|
<doctitle><![CDATA[<h1>Java Com Bridge (Jacob)</h1>]]></doctitle>
|
||||||
|
<bottom><![CDATA[<i>See Jacob-project on Sourceforge for more info</i>]]></bottom>
|
||||||
|
<tag name="todo" scope="all" description="To do:" />
|
||||||
|
<group title="Jacob COM" packages="com.jacob.com/**"/>
|
||||||
|
<group title="Higher Level Active X" packages="com.jacob.activeX/**"/>
|
||||||
|
<link offline="true" href="http://java.sun.com/j2se/1.4.2/docs/api/" packagelistLoc="C:\tmp"/>
|
||||||
|
<link href="http://java.sun.com/j2se/1.4.2/docs/api/"/>
|
||||||
|
</javadoc>
|
||||||
|
<defaultexcludes default="true"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- ======================================================================
|
||||||
|
Use this target to package all the files for a release
|
||||||
|
================================================================== -->
|
||||||
|
<target name="PackageRelease" depends="createDirectoryStructure,jacob_c_dll,jacob_java_jar_bin,javadoc">
|
||||||
|
|
||||||
|
<echo>Packaging release...</echo>
|
||||||
|
<zip
|
||||||
|
destfile="${install.dir}/jacob_${version}.zip">
|
||||||
|
<exclude name="**/CVS" />
|
||||||
|
<exclude name="**/*.obj" />
|
||||||
|
<exclude name="**/*.class" />
|
||||||
|
<zipfileset dir="${basedir}" prefix="jacob_${version}" includes="LICENSE.* version.properties" />
|
||||||
|
<zipfileset dir="${install.dir}" prefix="jacob_${version}" includes="jacob.jar jacob.dll"/>
|
||||||
|
<zipfileset dir="${basedir}" prefix="jacob_${version}" includes="docs/**" />
|
||||||
|
<zipfileset dir="${install.dir}" prefix="jacob_${version}" includes="docs/**"/>
|
||||||
|
</zip>
|
||||||
|
<zip
|
||||||
|
destfile="${install.dir}/jacob_${version}_src.zip">
|
||||||
|
<exclude name="**/CVS" />
|
||||||
|
<exclude name="**/*.obj" />
|
||||||
|
<exclude name="**/*.class" />
|
||||||
|
<exclude name="**/*.dll" />
|
||||||
|
<exclude name="**/*.exp" />
|
||||||
|
<exclude name="**/*.jar" />
|
||||||
|
<zipfileset dir="${basedir}" prefix="jacob_${version}" includes="src/**" />
|
||||||
|
<zipfileset dir="${basedir}" prefix="jacob_${version}" includes="docs/**" />
|
||||||
|
<zipfileset dir="${basedir}" prefix="jacob_${version}" includes="jni/**" />
|
||||||
|
<zipfileset dir="${basedir}" prefix="jacob_${version}" includes="samples/**" />
|
||||||
|
<zipfileset dir="${basedir}" prefix="jacob_${version}" includes="unittest/**" />
|
||||||
|
<zipfileset dir="${basedir}" prefix="jacob_${version}" includes="vstudio/**" />
|
||||||
|
<zipfileset dir="${basedir}" prefix="jacob_${version}" includes="build.xml, RELEASE.txt" />
|
||||||
|
<zipfileset dir="${basedir}" prefix="jacob_${version}" includes="LICENSE.* version.properties" />
|
||||||
|
</zip>
|
||||||
|
</target>
|
||||||
|
</project>
|
||||||
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
|
||||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in
|
|
||||||
* the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* 3. Redistributions in any form must be accompanied by information on
|
|
||||||
* how to obtain complete source code for the JACOB software.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package com.jacob.activeX;
|
|
||||||
|
|
||||||
import com.jacob.com.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class simulates com.ms.activeX.ActiveXComponent only as it used for
|
|
||||||
* creating Dispatch objects
|
|
||||||
*/
|
|
||||||
public class ActiveXComponent extends Dispatch {
|
|
||||||
/**
|
|
||||||
* @param progid
|
|
||||||
*/
|
|
||||||
public ActiveXComponent(String progid) {
|
|
||||||
super(progid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return actually returns this bject
|
|
||||||
*/
|
|
||||||
public Object getObject() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param name
|
|
||||||
* @param args
|
|
||||||
* @return Variant result of the invoke
|
|
||||||
*/
|
|
||||||
public Variant invoke(String name, Variant[] args) {
|
|
||||||
return Dispatch.callN(this, name, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param name property name
|
|
||||||
* @return Variant value of property
|
|
||||||
*/
|
|
||||||
public Variant getProperty(String name) {
|
|
||||||
return Dispatch.get(this, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param name
|
|
||||||
* @param arg
|
|
||||||
*/
|
|
||||||
public void setProperty(String name, Variant arg) {
|
|
||||||
Dispatch.put(this, name, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see com.jacob.com.Dispatch#finalize()
|
|
||||||
*/
|
|
||||||
protected void finalize() {
|
|
||||||
super.finalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
System.loadLibrary("jacob");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,589 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
|
||||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in
|
|
||||||
* the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* 3. Redistributions in any form must be accompanied by information on
|
|
||||||
* how to obtain complete source code for the JACOB software.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package com.jacob.com;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Object represents MS level dispatch object. You're going to live here
|
|
||||||
* a lot
|
|
||||||
*/
|
|
||||||
public class Dispatch extends JacobObject
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* This is public because Dispatch.cpp knows its name and accesses
|
|
||||||
* it directly to get the disptach 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;
|
|
||||||
|
|
||||||
public static final int LOCALE_SYSTEM_DEFAULT = 2048;
|
|
||||||
public static final int Method = 1;
|
|
||||||
public static final int Get = 2;
|
|
||||||
public static final int Put = 4;
|
|
||||||
public static final int PutRef = 8;
|
|
||||||
public static final int fdexNameCaseSensitive = 1;
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
// map args based on msdn doc
|
|
||||||
protected static Variant obj2variant(Object o) {
|
|
||||||
if (o == null)
|
|
||||||
return new Variant();
|
|
||||||
if (o instanceof Variant)
|
|
||||||
return (Variant) o;
|
|
||||||
if (o instanceof Integer)
|
|
||||||
return new Variant(((Integer) o).intValue());
|
|
||||||
if (o instanceof String)
|
|
||||||
return new Variant((String) o);
|
|
||||||
if (o instanceof Boolean)
|
|
||||||
return new Variant(((Boolean) o).booleanValue());
|
|
||||||
if (o instanceof Double)
|
|
||||||
return new Variant(((Double) o).doubleValue());
|
|
||||||
if (o instanceof Float)
|
|
||||||
return new Variant(((Float) o).floatValue());
|
|
||||||
if (o instanceof SafeArray)
|
|
||||||
return new Variant((SafeArray) o);
|
|
||||||
if (o instanceof Dispatch) {
|
|
||||||
Variant v = new Variant();
|
|
||||||
v.putObject((Dispatch) o);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
// automatically convert arrays using reflection
|
|
||||||
Class c1 = o.getClass();
|
|
||||||
SafeArray sa = null;
|
|
||||||
if (c1.isArray()) {
|
|
||||||
int len1 = Array.getLength(o);
|
|
||||||
Object first = Array.get(o, 0);
|
|
||||||
if (first.getClass().isArray()) {
|
|
||||||
int max = 0;
|
|
||||||
for (int i = 0; i < len1; i++) {
|
|
||||||
Object e1 = Array.get(o, 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(o, i);
|
|
||||||
for (int j = 0; j < Array.getLength(e1); j++) {
|
|
||||||
sa.setVariant(i, j, obj2variant(Array.get(e1, j)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sa = new SafeArray(Variant.VariantVariant, len1);
|
|
||||||
for (int i = 0; i < len1; i++) {
|
|
||||||
sa.setVariant(i, obj2variant(Array.get(o, i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Variant(sa);
|
|
||||||
}
|
|
||||||
throw new ClassCastException("cannot convert to Variant");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* same as above, for an array
|
|
||||||
* @param o
|
|
||||||
* @return Variant[]
|
|
||||||
*/
|
|
||||||
protected static Variant[] obj2variant(Object[] o) {
|
|
||||||
Variant vArg[] = new Variant[o.length];
|
|
||||||
for (int i = 0; i < o.length; i++) {
|
|
||||||
vArg[i] = obj2variant(o[i]);
|
|
||||||
}
|
|
||||||
return vArg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* zero argument constructor that sets the dispatch pointer to 0
|
|
||||||
*/
|
|
||||||
public Dispatch() {
|
|
||||||
m_pDispatch = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor that calls createInstance with progid. This is the
|
|
||||||
* constructor used by the ActiveXComponent
|
|
||||||
*
|
|
||||||
* @param requestedProgramId
|
|
||||||
*/
|
|
||||||
public Dispatch(String requestedProgramId) {
|
|
||||||
programId = requestedProgramId;
|
|
||||||
createInstance(requestedProgramId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return a different interface by IID string
|
|
||||||
*
|
|
||||||
* @param iid
|
|
||||||
* @return Dispatch a disptach that matches ??
|
|
||||||
*/
|
|
||||||
public native Dispatch QueryInterface(String iid);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor that only gets called from JNI
|
|
||||||
*
|
|
||||||
* @param pDisp
|
|
||||||
*/
|
|
||||||
protected Dispatch(int pDisp) {
|
|
||||||
m_pDispatch = pDisp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* native call createIstnace only used by the constructor with the same parm
|
|
||||||
* type could this be private?
|
|
||||||
*
|
|
||||||
* @param progid
|
|
||||||
*/
|
|
||||||
protected native void createInstance(String progid);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* call this to explicitly release the com object before gc
|
|
||||||
*/
|
|
||||||
public native void release();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* not implemented yet
|
|
||||||
*
|
|
||||||
* @param disp
|
|
||||||
* @param name
|
|
||||||
* @param val
|
|
||||||
* @throws ClassCastException
|
|
||||||
* because???
|
|
||||||
*/
|
|
||||||
public static void put_Casesensitive(Object disp, String name, Object val) {
|
|
||||||
throw new ClassCastException("not implemented yet");
|
|
||||||
}
|
|
||||||
|
|
||||||
// eliminate _Guid arg
|
|
||||||
public static void invokeSubv(Object disp, String name, int dispID,
|
|
||||||
int lcid, int wFlags, Variant[] vArg, int[] uArgErr) {
|
|
||||||
invokev(disp, name, dispID, lcid, wFlags, vArg, uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void invokeSubv(Object disp, String name, int wFlags,
|
|
||||||
Variant[] vArg, int[] uArgErr) {
|
|
||||||
invokev(disp, name, 0, LOCALE_SYSTEM_DEFAULT, wFlags, vArg, uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void invokeSubv(Object disp, int dispID, int wFlags,
|
|
||||||
Variant[] vArg, int[] uArgErr) {
|
|
||||||
invokev(disp, null, dispID, LOCALE_SYSTEM_DEFAULT, wFlags, vArg,
|
|
||||||
uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant callN_CaseSensitive(Object disp, String name,
|
|
||||||
Object[] values) {
|
|
||||||
throw new ClassCastException("not implemented yet");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSubN(Object disp, String name, Object[] args) {
|
|
||||||
invokeSubv(disp, name, Method | Get, obj2variant(args),
|
|
||||||
new int[args.length]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSubN(Object disp, int dispID, Object[] args) {
|
|
||||||
invokeSubv(disp, dispID, Method | Get, obj2variant(args),
|
|
||||||
new int[args.length]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getIDOfName(Object disp, String name) {
|
|
||||||
int ids[] = getIDsOfNames(disp, LOCALE_SYSTEM_DEFAULT,
|
|
||||||
new String[] { name });
|
|
||||||
return ids[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// eliminated _Guid argument
|
|
||||||
public static native int[] getIDsOfNames(Object disp, int lcid,
|
|
||||||
String[] names);
|
|
||||||
|
|
||||||
// eliminated _Guid argument
|
|
||||||
public static int[] getIDsOfNames(Object disp, String[] names) {
|
|
||||||
return getIDsOfNames(disp, LOCALE_SYSTEM_DEFAULT, names);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant callN(Object disp, String name, Object[] args) {
|
|
||||||
return invokev(disp, name, Method | Get, obj2variant(args),
|
|
||||||
new int[args.length]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant callN(Object disp, int dispID, Object[] args) {
|
|
||||||
return invokev(disp, dispID, Method | Get, obj2variant(args),
|
|
||||||
new int[args.length]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant invoke(Object disp, String name, int dispID,
|
|
||||||
int lcid, int wFlags, Object[] oArg, int[] uArgErr) {
|
|
||||||
return invokev(disp, name, dispID, lcid, wFlags, obj2variant(oArg),
|
|
||||||
uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant invoke(Object disp, String name, int wFlags,
|
|
||||||
Object[] oArg, int[] uArgErr) {
|
|
||||||
return invokev(disp, name, wFlags, obj2variant(oArg), uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant invoke(Object disp, int dispID, int wFlags,
|
|
||||||
Object[] oArg, int[] uArgErr) {
|
|
||||||
return invokev(disp, dispID, wFlags, obj2variant(oArg), uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, String name) {
|
|
||||||
return callN(disp, name, new Variant[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, String name, Object a1) {
|
|
||||||
return callN(disp, name, new Object[] { a1 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, String name, Object a1, Object a2) {
|
|
||||||
return callN(disp, name, new Object[] { a1, a2 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3) {
|
|
||||||
return callN(disp, name, new Object[] { a1, a2, a3 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3, Object a4) {
|
|
||||||
return callN(disp, name, new Object[] { a1, a2, a3, a4 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5) {
|
|
||||||
return callN(disp, name, new Object[] { a1, a2, a3, a4, a5 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6) {
|
|
||||||
return callN(disp, name, new Object[] { a1, a2, a3, a4, a5, a6 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6, Object a7) {
|
|
||||||
return callN(disp, name, new Object[] { a1, a2, a3, a4, a5, a6, a7 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) {
|
|
||||||
return callN(disp, name,
|
|
||||||
new Object[] { a1, a2, a3, a4, a5, a6, a7, a8 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, int dispid) {
|
|
||||||
return callN(disp, dispid, new Variant[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, int dispid, Object a1) {
|
|
||||||
return callN(disp, dispid, new Object[] { a1 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, int dispid, Object a1, Object a2) {
|
|
||||||
return callN(disp, dispid, new Object[] { a1, a2 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3) {
|
|
||||||
return callN(disp, dispid, new Object[] { a1, a2, a3 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3, Object a4) {
|
|
||||||
return callN(disp, dispid, new Object[] { a1, a2, a3, a4 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5) {
|
|
||||||
return callN(disp, dispid, new Object[] { a1, a2, a3, a4, a5 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6) {
|
|
||||||
return callN(disp, dispid, new Object[] { a1, a2, a3, a4, a5, a6 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6, Object a7) {
|
|
||||||
return callN(disp, dispid, new Object[] { a1, a2, a3, a4, a5, a6, a7 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant call(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) {
|
|
||||||
return callN(disp, dispid, new Object[] { a1, a2, a3, a4, a5, a6, a7,
|
|
||||||
a8 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void put(Object disp, String name, Object val) {
|
|
||||||
invoke(disp, name, Put, new Object[] { val }, new int[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void put(Object disp, int dispid, Object val) {
|
|
||||||
invoke(disp, dispid, Put, new Object[] { val }, new int[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// removed _Guid argument
|
|
||||||
public static native Variant invokev(Object disp, String name, int dispID,
|
|
||||||
int lcid, int wFlags, Variant[] vArg, int[] uArgErr);
|
|
||||||
|
|
||||||
public static Variant invokev(Object disp, String name, int wFlags,
|
|
||||||
Variant[] vArg, int[] uArgErr) {
|
|
||||||
if (!(disp instanceof Dispatch))
|
|
||||||
throw new ClassCastException("Dispatch object expected");
|
|
||||||
return invokev(disp, name, 0, LOCALE_SYSTEM_DEFAULT, wFlags, vArg,
|
|
||||||
uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant invokev(Object disp, String name, int wFlags,
|
|
||||||
Variant[] vArg, int[] uArgErr, int wFlagsEx) {
|
|
||||||
if (!(disp instanceof Dispatch))
|
|
||||||
throw new ClassCastException("Dispatch object expected");
|
|
||||||
// do not implement IDispatchEx for now
|
|
||||||
return invokev(disp, name, 0, LOCALE_SYSTEM_DEFAULT, wFlags, vArg,
|
|
||||||
uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant invokev(Object disp, int dispID, int wFlags,
|
|
||||||
Variant[] vArg, int[] uArgErr) {
|
|
||||||
if (!(disp instanceof Dispatch))
|
|
||||||
throw new ClassCastException("Dispatch object expected");
|
|
||||||
return invokev(disp, null, dispID, LOCALE_SYSTEM_DEFAULT, wFlags, vArg,
|
|
||||||
uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// removed _Guid argument
|
|
||||||
public static void invokeSub(Object disp, String name, int dispid,
|
|
||||||
int lcid, int wFlags, Object[] oArg, int[] uArgErr) {
|
|
||||||
invokeSubv(disp, name, dispid, lcid, wFlags, obj2variant(oArg), uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void invokeSub(Object disp, String name, int wFlags,
|
|
||||||
Object[] oArg, int[] uArgErr) {
|
|
||||||
invokeSub(disp, name, 0, LOCALE_SYSTEM_DEFAULT, wFlags, oArg, uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void invokeSub(Object disp, int dispid, int wFlags,
|
|
||||||
Object[] oArg, int[] uArgErr) {
|
|
||||||
invokeSub(disp, null, dispid, LOCALE_SYSTEM_DEFAULT, wFlags, oArg,
|
|
||||||
uArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, String name) {
|
|
||||||
callSubN(disp, name, new Object[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, String name, Object a1) {
|
|
||||||
callSubN(disp, name, new Object[] { a1 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, String name, Object a1, Object a2) {
|
|
||||||
callSubN(disp, name, new Object[] { a1, a2 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3) {
|
|
||||||
callSubN(disp, name, new Object[] { a1, a2, a3 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3, Object a4) {
|
|
||||||
callSubN(disp, name, new Object[] { a1, a2, a3, a4 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5) {
|
|
||||||
callSubN(disp, name, new Object[] { a1, a2, a3, a4, a5 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6) {
|
|
||||||
callSubN(disp, name, new Object[] { a1, a2, a3, a4, a5, a6 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6, Object a7) {
|
|
||||||
callSubN(disp, name, new Object[] { a1, a2, a3, a4, a5, a6, a7 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, String name, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) {
|
|
||||||
callSubN(disp, name, new Object[] { a1, a2, a3, a4, a5, a6, a7, a8 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, int dispid) {
|
|
||||||
callSubN(disp, dispid, new Object[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, int dispid, Object a1) {
|
|
||||||
callSubN(disp, dispid, new Object[] { a1 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, int dispid, Object a1, Object a2) {
|
|
||||||
callSubN(disp, dispid, new Object[] { a1, a2 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3) {
|
|
||||||
callSubN(disp, dispid, new Object[] { a1, a2, a3 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3, Object a4) {
|
|
||||||
callSubN(disp, dispid, new Object[] { a1, a2, a3, a4 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5) {
|
|
||||||
callSubN(disp, dispid, new Object[] { a1, a2, a3, a4, a5 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6) {
|
|
||||||
callSubN(disp, dispid, new Object[] { a1, a2, a3, a4, a5, a6 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6, Object a7) {
|
|
||||||
callSubN(disp, dispid, new Object[] { a1, a2, a3, a4, a5, a6, a7 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void callSub(Object disp, int dispid, Object a1, Object a2,
|
|
||||||
Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) {
|
|
||||||
callSubN(disp, dispid, new Object[] { a1, a2, a3, a4, a5, a6, a7, a8 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant get(Object disp, String name) {
|
|
||||||
return invokev(disp, name, Get, new Variant[0], new int[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant get(Object disp, int dispid) {
|
|
||||||
return invokev(disp, dispid, Get, new Variant[0], new int[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putRef(Object disp, String name, Object val) {
|
|
||||||
invoke(disp, name, PutRef, new Object[] { val }, new int[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putRef(Object disp, int dispid, Object val) {
|
|
||||||
invoke(disp, dispid, PutRef, new Object[] { val }, new int[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variant get_CaseSensitive(Object disp, String name) {
|
|
||||||
throw new ClassCastException("not implemented yet");
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
System.loadLibrary("jacob");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void finalize() {
|
|
||||||
//System.out.println("Dispatch finalize start");
|
|
||||||
if (m_pDispatch != 0)
|
|
||||||
release();
|
|
||||||
//System.out.println("Dispatch finalize end");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
|
||||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in
|
|
||||||
* the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* 3. Redistributions in any form must be accompanied by information on
|
|
||||||
* how to obtain complete source code for the JACOB software.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package com.jacob.com;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ???
|
|
||||||
*/
|
|
||||||
public class DispatchEvents extends JacobObject {
|
|
||||||
int m_pConnPtProxy = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param src
|
|
||||||
* @param sink
|
|
||||||
*/
|
|
||||||
public DispatchEvents(Dispatch src, Object sink) {
|
|
||||||
init(src, sink);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param src
|
|
||||||
* @param sink
|
|
||||||
* @param progId
|
|
||||||
*/
|
|
||||||
public DispatchEvents(Dispatch src, Object sink, String progId) {
|
|
||||||
init2(src, sink, progId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// hook up a connection point proxy object
|
|
||||||
// event methods on the sink object will be called
|
|
||||||
// by name with a signature of <name>(Variant[] args)
|
|
||||||
protected native void init(Dispatch src, Object sink);
|
|
||||||
|
|
||||||
protected native void init2(Dispatch src, Object sink, String progId);
|
|
||||||
|
|
||||||
// call this to explicitly release the com object before gc
|
|
||||||
public native void release();
|
|
||||||
|
|
||||||
protected void finalize() {
|
|
||||||
//System.out.println("DispatchEvents finalize start");
|
|
||||||
if (m_pConnPtProxy != 0)
|
|
||||||
release();
|
|
||||||
//System.out.println("DispatchEvents finalize end");
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
System.loadLibrary("jacob");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
|
||||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in
|
|
||||||
* the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* 3. Redistributions in any form must be accompanied by information on
|
|
||||||
* how to obtain complete source code for the JACOB software.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package com.jacob.com;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public JacobObject() {
|
|
||||||
ROT.addObject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void release() {
|
|
||||||
// currently does nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
|
||||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in
|
|
||||||
* the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* 3. Redistributions in any form must be accompanied by information on
|
|
||||||
* how to obtain complete source code for the JACOB software.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package com.jacob.com;
|
|
||||||
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Running Object Table (ROT) maps each thread to a vector 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. Conceptually, this is similar to the ThreadLocal class of
|
|
||||||
* Java 1.2 but we are also supporting Java 1.6 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. If we leave this job to the garbage
|
|
||||||
* collector, then finalize might get called from a separate thread which is not
|
|
||||||
* initialized for COM, and also the component itself may have been freed.
|
|
||||||
*/
|
|
||||||
public abstract class ROT {
|
|
||||||
private static Hashtable rot = new Hashtable();
|
|
||||||
|
|
||||||
protected static void addThread() {
|
|
||||||
String t_name = Thread.currentThread().getName();
|
|
||||||
if (rot.contains(t_name))
|
|
||||||
return;
|
|
||||||
Vector v = new Vector();
|
|
||||||
rot.put(t_name, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void clearObjects() {
|
|
||||||
String t_name = Thread.currentThread().getName();
|
|
||||||
Vector v = (Vector) rot.get(t_name);
|
|
||||||
if (v != null) {
|
|
||||||
while (!v.isEmpty()) {
|
|
||||||
JacobObject o = (JacobObject) v.elementAt(0);
|
|
||||||
//System.out.println(t_name + "
|
|
||||||
// release:"+o+"->"+o.getClass().getName());
|
|
||||||
if (o != null)
|
|
||||||
o.release();
|
|
||||||
v.removeElementAt(0);
|
|
||||||
}
|
|
||||||
rot.remove(t_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void addObject(JacobObject o) {
|
|
||||||
String t_name = Thread.currentThread().getName();
|
|
||||||
//System.out.println(t_name + " add:"+o+"->"+o.getClass().getName());
|
|
||||||
Vector v = (Vector) rot.get(t_name);
|
|
||||||
if (v == null) {
|
|
||||||
// this thread has not been initialized as a COM thread
|
|
||||||
// so make it part of MTA for backwards compatibility
|
|
||||||
ComThread.InitMTA(false);
|
|
||||||
addThread();
|
|
||||||
v = (Vector) rot.get(t_name);
|
|
||||||
}
|
|
||||||
if (v != null) {
|
|
||||||
v.addElement(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
System.loadLibrary("jacob");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,372 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
|
||||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in
|
|
||||||
* the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* 3. Redistributions in any form must be accompanied by information on
|
|
||||||
* how to obtain complete source code for the JACOB software.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package com.jacob.com;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The multi-format data type used for all call backs and most
|
|
||||||
* communications between Java and COM
|
|
||||||
*/
|
|
||||||
public class Variant extends JacobObject implements java.io.Serializable
|
|
||||||
{
|
|
||||||
int m_pVariant = 0;
|
|
||||||
|
|
||||||
public static final short VariantEmpty = 0;
|
|
||||||
public static final short VariantNull = 1;
|
|
||||||
public static final short VariantShort = 2;
|
|
||||||
public static final short VariantInt = 3;
|
|
||||||
public static final short VariantFloat = 4;
|
|
||||||
public static final short VariantDouble = 5;
|
|
||||||
public static final short VariantCurrency = 6;
|
|
||||||
public static final short VariantDate = 7;
|
|
||||||
public static final short VariantString = 8;
|
|
||||||
public static final short VariantDispatch = 9;
|
|
||||||
public static final short VariantError = 10;
|
|
||||||
public static final short VariantBoolean = 11;
|
|
||||||
public static final short VariantVariant = 12;
|
|
||||||
public static final short VariantObject = 13;
|
|
||||||
public static final short VariantByte = 17;
|
|
||||||
public static final short VariantTypeMask = 4095;
|
|
||||||
public static final short VariantArray = 8192;
|
|
||||||
public static final short VariantByref = 16384;
|
|
||||||
|
|
||||||
public native int toInt();
|
|
||||||
public native double toDate();
|
|
||||||
public native boolean toBoolean();
|
|
||||||
public native EnumVariant toEnumVariant();
|
|
||||||
|
|
||||||
public native void getNull();
|
|
||||||
public native void putNull();
|
|
||||||
|
|
||||||
public native Variant cloneIndirect();
|
|
||||||
public native double toDouble();
|
|
||||||
public native long toCurrency();
|
|
||||||
|
|
||||||
// superceded by SafeArray
|
|
||||||
public void putVariantArray(Variant[] in)
|
|
||||||
{
|
|
||||||
throw new ComFailException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
// superceded by SafeArray
|
|
||||||
public Variant[] getVariantArray()
|
|
||||||
{
|
|
||||||
throw new ComFailException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
// superceded by SafeArray
|
|
||||||
public void putByteArray(Object in)
|
|
||||||
{
|
|
||||||
throw new ComFailException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
public native void putShortRef(short in);
|
|
||||||
public native void putIntRef(int in);
|
|
||||||
public native void putDoubleRef(double in);
|
|
||||||
public native void putDateRef(double in);
|
|
||||||
public native void putStringRef(String in);
|
|
||||||
public native short getShortRef();
|
|
||||||
public native int getIntRef();
|
|
||||||
public native void putShort(short in);
|
|
||||||
public native short getShort();
|
|
||||||
public native double getDoubleRef();
|
|
||||||
public native double getDateRef();
|
|
||||||
public native String getStringRef();
|
|
||||||
|
|
||||||
// superceded by SafeArray
|
|
||||||
public Object toCharArray()
|
|
||||||
{
|
|
||||||
throw new ComFailException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
public native void VariantClear();
|
|
||||||
public native Dispatch toDispatch();
|
|
||||||
public native Object clone();
|
|
||||||
public native String toString();
|
|
||||||
public native int getInt();
|
|
||||||
public native double getDate();
|
|
||||||
public native void putInt(int in);
|
|
||||||
public native void putDate(double in);
|
|
||||||
public native byte toByte();
|
|
||||||
|
|
||||||
public Object getDispatch() { return toDispatch(); }
|
|
||||||
public void putDispatch(Object in) { putObject(in); }
|
|
||||||
|
|
||||||
public native boolean getBoolean();
|
|
||||||
public native byte getByte();
|
|
||||||
public native void putBoolean(boolean in);
|
|
||||||
public native void putByte(byte in);
|
|
||||||
public native int toError();
|
|
||||||
|
|
||||||
public Object toObject()
|
|
||||||
{
|
|
||||||
return toDispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
public native void getEmpty();
|
|
||||||
public native void putEmpty();
|
|
||||||
public native int getError();
|
|
||||||
public native void putError(int in);
|
|
||||||
public native double getDouble();
|
|
||||||
public Object getObject()
|
|
||||||
{
|
|
||||||
return toDispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
public native void putCurrency(long in);
|
|
||||||
|
|
||||||
public native void putObject(Object in);
|
|
||||||
|
|
||||||
public native void putDouble(double in);
|
|
||||||
public native long getCurrency();
|
|
||||||
public native void putFloatRef(float in);
|
|
||||||
public native void putCurrencyRef(long in);
|
|
||||||
public native void putErrorRef(int in);
|
|
||||||
public native void putBooleanRef(boolean in);
|
|
||||||
|
|
||||||
public void putObjectRef(Object in)
|
|
||||||
{
|
|
||||||
putObject(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
public native void putByteRef(byte in);
|
|
||||||
public native String getString();
|
|
||||||
public native void putString(String in);
|
|
||||||
public native float getFloatRef();
|
|
||||||
public native long getCurrencyRef();
|
|
||||||
public native int getErrorRef();
|
|
||||||
public native boolean getBooleanRef();
|
|
||||||
public native Object getObjectRef();
|
|
||||||
public native byte getByteRef();
|
|
||||||
public native float toFloat();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default toSafeArray makes a deep copy due to the fact
|
|
||||||
* that this Variant owns the embedded SafeArray and will
|
|
||||||
* destroy it when it gc's
|
|
||||||
*/
|
|
||||||
public SafeArray toSafeArray()
|
|
||||||
{
|
|
||||||
return toSafeArray(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public native SafeArray toSafeArray(boolean deepCopy);
|
|
||||||
public native void putSafeArrayRef(SafeArray in);
|
|
||||||
public native void putSafeArray(SafeArray in);
|
|
||||||
|
|
||||||
public native void noParam();
|
|
||||||
|
|
||||||
// superceded by SafeArray
|
|
||||||
public void putCharArray(Object in)
|
|
||||||
{
|
|
||||||
throw new ComFailException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
public native float getFloat();
|
|
||||||
public native void putFloat(float in);
|
|
||||||
|
|
||||||
public void putDispatchRef(Object in) { putDispatch(in); }
|
|
||||||
public Object getDispatchRef() { return getDispatch(); }
|
|
||||||
|
|
||||||
// superceded by SafeArray
|
|
||||||
public void putVariantArrayRef(Variant[] in)
|
|
||||||
{
|
|
||||||
throw new ClassCastException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
// superceded by SafeArray
|
|
||||||
public Variant[] getVariantArrayRef()
|
|
||||||
{
|
|
||||||
throw new ClassCastException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
public native void changeType(short in);
|
|
||||||
|
|
||||||
public void changeType(int in)
|
|
||||||
{
|
|
||||||
changeType((short)in);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object toScriptObject() { return toDispatch(); }
|
|
||||||
|
|
||||||
public Variant()
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
putEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variant(int in)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
putInt(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variant(double in)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
putDouble(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variant(boolean in)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
putBoolean(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variant(String in)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
putString(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variant(SafeArray in,boolean fByRef)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
if (fByRef) {
|
|
||||||
putSafeArrayRef(in);
|
|
||||||
} else {
|
|
||||||
putSafeArray(in);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variant(Object in)
|
|
||||||
{
|
|
||||||
this(in, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variant(Object o,boolean fByRef)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
if (o == null) {
|
|
||||||
putEmpty();
|
|
||||||
} else if (o instanceof Integer) {
|
|
||||||
if (fByRef) putIntRef(((Integer)o).intValue());
|
|
||||||
else putInt(((Integer)o).intValue());
|
|
||||||
} else if (o instanceof String) {
|
|
||||||
if (fByRef) putStringRef((String)o);
|
|
||||||
else putString((String)o);
|
|
||||||
} else if (o instanceof Boolean) {
|
|
||||||
if (fByRef) putBooleanRef(((Boolean)o).booleanValue());
|
|
||||||
else putBoolean(((Boolean)o).booleanValue());
|
|
||||||
} else if (o instanceof Double) {
|
|
||||||
if (fByRef) putDoubleRef(((Double)o).doubleValue());
|
|
||||||
else putDouble(((Double)o).doubleValue());
|
|
||||||
} else if (o instanceof Float) {
|
|
||||||
if (fByRef) putFloatRef(((Float)o).floatValue());
|
|
||||||
else putFloat(((Float)o).floatValue());
|
|
||||||
} else if (o instanceof SafeArray) {
|
|
||||||
if (fByRef) putSafeArrayRef((SafeArray)o);
|
|
||||||
else putSafeArray((SafeArray)o);
|
|
||||||
} else {
|
|
||||||
if (fByRef) putObjectRef(o); else putObject(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//weird constructors
|
|
||||||
public Variant(int in,int in1)
|
|
||||||
{
|
|
||||||
throw new ComFailException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variant(int in,boolean in1)
|
|
||||||
{
|
|
||||||
throw new ComFailException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variant(int in,double in1)
|
|
||||||
{
|
|
||||||
throw new ComFailException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variant(int in,Object in1)
|
|
||||||
{
|
|
||||||
throw new ComFailException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
public native short getvt();
|
|
||||||
public native short toShort();
|
|
||||||
|
|
||||||
// call this to explicitly release the com object before gc
|
|
||||||
public native void release();
|
|
||||||
|
|
||||||
protected native void init();
|
|
||||||
|
|
||||||
protected void finalize()
|
|
||||||
{
|
|
||||||
//System.out.println("Variant finalize start:"+m_pVariant);
|
|
||||||
if (m_pVariant != 0) release();
|
|
||||||
//System.out.println("Variant finalize end");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// superceded by SafeArray
|
|
||||||
public Variant[] toVariantArray()
|
|
||||||
{
|
|
||||||
throw new ClassCastException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
// superceded by SafeArray
|
|
||||||
public Object toByteArray()
|
|
||||||
{
|
|
||||||
throw new ClassCastException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
System.loadLibrary("jacob");
|
|
||||||
}
|
|
||||||
|
|
||||||
// serialization support
|
|
||||||
private void writeObject(java.io.ObjectOutputStream oos)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Save(oos);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readObject(java.io.ObjectInputStream ois)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Load(ois);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// is the variant null or empty or error or null disp
|
|
||||||
public native boolean isNull();
|
|
||||||
|
|
||||||
public native void Save(java.io.OutputStream os)
|
|
||||||
throws java.io.IOException;
|
|
||||||
|
|
||||||
public native void Load(java.io.InputStream is)
|
|
||||||
throws java.io.IOException;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ xmlns="http://www.w3.org/TR/REC-html40">
|
|||||||
<meta name=ProgId content=Word.Document>
|
<meta name=ProgId content=Word.Document>
|
||||||
<meta name=Generator content="Microsoft Word 11">
|
<meta name=Generator content="Microsoft Word 11">
|
||||||
<meta name=Originator content="Microsoft Word 11">
|
<meta name=Originator content="Microsoft Word 11">
|
||||||
<link rel=File-List href="EventsAndCallBacks_files/filelist.xml">
|
<link rel=File-List href="EventCallbacks_files/filelist.xml">
|
||||||
<title>Jacob can register Java classes for MS application events or callbacks</title>
|
<title>Jacob can register Java classes for MS application events or callbacks</title>
|
||||||
<!--[if gte mso 9]><xml>
|
<!--[if gte mso 9]><xml>
|
||||||
<o:OfficeDocumentSettings>
|
<o:OfficeDocumentSettings>
|
||||||
@@ -75,6 +75,38 @@ div.Section1
|
|||||||
mso-level-number-position:left;
|
mso-level-number-position:left;
|
||||||
margin-left:42.0pt;
|
margin-left:42.0pt;
|
||||||
text-indent:-24.0pt;}
|
text-indent:-24.0pt;}
|
||||||
|
@list l0:level2
|
||||||
|
{mso-level-tab-stop:1.0in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l0:level3
|
||||||
|
{mso-level-tab-stop:1.5in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l0:level4
|
||||||
|
{mso-level-tab-stop:2.0in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l0:level5
|
||||||
|
{mso-level-tab-stop:2.5in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l0:level6
|
||||||
|
{mso-level-tab-stop:3.0in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l0:level7
|
||||||
|
{mso-level-tab-stop:3.5in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l0:level8
|
||||||
|
{mso-level-tab-stop:4.0in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l0:level9
|
||||||
|
{mso-level-tab-stop:4.5in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
@list l1
|
@list l1
|
||||||
{mso-list-id:1316765558;
|
{mso-list-id:1316765558;
|
||||||
mso-list-type:hybrid;
|
mso-list-type:hybrid;
|
||||||
@@ -85,6 +117,38 @@ div.Section1
|
|||||||
mso-level-number-position:left;
|
mso-level-number-position:left;
|
||||||
margin-left:42.0pt;
|
margin-left:42.0pt;
|
||||||
text-indent:-24.0pt;}
|
text-indent:-24.0pt;}
|
||||||
|
@list l1:level2
|
||||||
|
{mso-level-tab-stop:1.0in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l1:level3
|
||||||
|
{mso-level-tab-stop:1.5in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l1:level4
|
||||||
|
{mso-level-tab-stop:2.0in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l1:level5
|
||||||
|
{mso-level-tab-stop:2.5in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l1:level6
|
||||||
|
{mso-level-tab-stop:3.0in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l1:level7
|
||||||
|
{mso-level-tab-stop:3.5in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l1:level8
|
||||||
|
{mso-level-tab-stop:4.0in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
|
@list l1:level9
|
||||||
|
{mso-level-tab-stop:4.5in;
|
||||||
|
mso-level-number-position:left;
|
||||||
|
text-indent:-.25in;}
|
||||||
ol
|
ol
|
||||||
{margin-bottom:0in;}
|
{margin-bottom:0in;}
|
||||||
ul
|
ul
|
||||||
@@ -124,48 +188,48 @@ is:</p>
|
|||||||
<p class=MsoPlainText><o:p> </o:p></p>
|
<p class=MsoPlainText><o:p> </o:p></p>
|
||||||
|
|
||||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
|
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>1)<span
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>1)<span
|
||||||
style='font:7.0pt "Times New Roman"'>
|
style='font:7.0pt "Times New Roman"'>
|
||||||
</span></span></span><![endif]>Application thread creates an instance of the
|
</span></span></span><![endif]>Application thread creates an instance of the
|
||||||
event handler and registers it with Jacob</p>
|
event handler and registers it with Jacob</p>
|
||||||
|
|
||||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
|
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>2)<span
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>2)<span
|
||||||
style='font:7.0pt "Times New Roman"'>
|
style='font:7.0pt "Times New Roman"'>
|
||||||
</span></span></span><![endif]>The application continues on doing other work.</p>
|
</span></span></span><![endif]>The application continues on doing other work.</p>
|
||||||
|
|
||||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
|
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>3)<span
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>3)<span
|
||||||
style='font:7.0pt "Times New Roman"'>
|
style='font:7.0pt "Times New Roman"'>
|
||||||
</span></span></span><![endif]>Some time later, the MS application takes some
|
</span></span></span><![endif]>Some time later, the MS application takes some
|
||||||
action and initiates the event callback.</p>
|
action and initiates the event callback.</p>
|
||||||
|
|
||||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
|
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>4)<span
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>4)<span
|
||||||
style='font:7.0pt "Times New Roman"'>
|
style='font:7.0pt "Times New Roman"'>
|
||||||
</span></span></span><![endif]>The Java VM receives the event and spins up a
|
</span></span></span><![endif]>The Java VM receives the event and spins up a
|
||||||
new thread to handle it.</p>
|
new thread to handle it.</p>
|
||||||
|
|
||||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
|
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>5)<span
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>5)<span
|
||||||
style='font:7.0pt "Times New Roman"'>
|
style='font:7.0pt "Times New Roman"'>
|
||||||
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
||||||
in the <span class=SpellE>dll</span> is called by the VM.</p>
|
in the <span class=SpellE>dll</span> is called by the VM.</p>
|
||||||
|
|
||||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
|
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>6)<span
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>6)<span
|
||||||
style='font:7.0pt "Times New Roman"'>
|
style='font:7.0pt "Times New Roman"'>
|
||||||
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
||||||
creates Variant objects to handle the parameters of the passed in event.</p>
|
creates Variant objects to handle the parameters of the passed in event.</p>
|
||||||
|
|
||||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
|
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>7)<span
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>7)<span
|
||||||
style='font:7.0pt "Times New Roman"'>
|
style='font:7.0pt "Times New Roman"'>
|
||||||
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
||||||
@@ -173,7 +237,7 @@ uses reflection to map the event name to a method name with the exact same
|
|||||||
name.</p>
|
name.</p>
|
||||||
|
|
||||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
|
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>8)<span
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>8)<span
|
||||||
style='font:7.0pt "Times New Roman"'>
|
style='font:7.0pt "Times New Roman"'>
|
||||||
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
||||||
@@ -214,60 +278,66 @@ class loader of the event handler class.</p>
|
|||||||
<p class=MsoPlainText><o:p> </o:p></p>
|
<p class=MsoPlainText><o:p> </o:p></p>
|
||||||
|
|
||||||
<p class=MsoPlainText>The Jacob <span class=SpellE>EventProxy</span> class has
|
<p class=MsoPlainText>The Jacob <span class=SpellE>EventProxy</span> class has
|
||||||
been modified (off of the 1.8 tree) so that it takes a two step approach to towards
|
been modified (off of the 1.8 tree) so that it takes a two step approach to
|
||||||
fixing these problems.</p>
|
towards fixing these problems.</p>
|
||||||
|
|
||||||
<p class=MsoPlainText><span style='mso-tab-count:1'> </span><span
|
<p class=MsoPlainText><span style='mso-tab-count:2'> </span></p>
|
||||||
style='mso-tab-count:1'> </span></p>
|
|
||||||
|
|
||||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
l0 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
l0 level1 lfo4;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>1)<span
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>1)<span
|
||||||
style='font:7.0pt "Times New Roman"'>
|
style='font:7.0pt "Times New Roman"'>
|
||||||
|
</span></span></span><![endif]>The <span class=SpellE>EventProxy</span>
|
||||||
|
constructor now accepts an extra object, an instance of the Variant class.<span
|
||||||
|
style='mso-spacerun:yes'> </span>This gives the <span class=SpellE>EventProxy</span>
|
||||||
|
a way to get to the Variant class and thus to its <span class=SpellE>classloader</span>.
|
||||||
|
All of the callers of the constructor have been modified to pass a Variant
|
||||||
|
object to the <span class=SpellE>EventProxy</span> without programmer
|
||||||
|
intervention.</p>
|
||||||
|
|
||||||
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
|
l0 level1 lfo4;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>2)<span
|
||||||
|
style='font:7.0pt "Times New Roman"'>
|
||||||
</span></span></span><![endif]><span class=SpellE>EventProxy</span> first
|
</span></span></span><![endif]><span class=SpellE>EventProxy</span> first
|
||||||
attempts to locate the Variant class using <span class=SpellE>FindClass</span>()</p>
|
attempts to locate the Variant class using <span class=SpellE>FindClass</span>()</p>
|
||||||
|
|
||||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
l0 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
l0 level1 lfo4;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>2)<span
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>3)<span
|
||||||
style='font:7.0pt "Times New Roman"'>
|
style='font:7.0pt "Times New Roman"'>
|
||||||
</span></span></span><![endif]>Failing that, it looks to see if the event
|
</span></span></span><![endif]>Failing that, it looks to see if a variant
|
||||||
callback object implements <span class=SpellE><span class=GramE>getVariantClass</span></span><span
|
object had been passed in. If so, it calls <span class=GramE>class(</span>) and
|
||||||
class=GramE>(</span>) that returns the <span class=SpellE>Variant.class</span>
|
goes from there.<span style='mso-spacerun:yes'> </span></p>
|
||||||
object.<span style='mso-spacerun:yes'> </span>If so, it uses that class to
|
|
||||||
create variants for the callback parameters.</p>
|
|
||||||
|
|
||||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||||
l0 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
l0 level1 lfo4;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>3)<span
|
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>4)<span
|
||||||
style='font:7.0pt "Times New Roman"'>
|
style='font:7.0pt "Times New Roman"'>
|
||||||
</span></span></span><![endif]>If all that fails, it logs a message and then
|
</span></span></span><![endif]>If all that fails, it logs a message and then
|
||||||
fails in the spectacular fashion of the previous versions.</p>
|
fails in the spectacular fashion of the previous versions.</p>
|
||||||
|
|
||||||
<p class=MsoPlainText><o:p> </o:p></p>
|
<p class=MsoPlainText><o:p> </o:p></p>
|
||||||
|
|
||||||
<p class=MsoPlainText>This means developers can receive call back events in JWS
|
<p class=MsoPlainText>Developers can receive call back events in JWS other Java
|
||||||
other Java launching programs by implementing <span class=SpellE><span
|
launching programs without implementing any additional code.<span
|
||||||
class=GramE>getVariantClass</span></span><span class=GramE>(</span>) on all of
|
style='mso-spacerun:yes'> </span>They should be aware that their callback
|
||||||
their classes that receive Microsoft Events.<span style='mso-spacerun:yes'>
|
methods may need to set the class <span class=GramE>loader.:</span></p>
|
||||||
</span>The <span class=SpellE><span class=GramE>getVariantClass</span></span><span
|
|
||||||
class=GramE>(</span>) method has the added benefit of providing a spot for the
|
|
||||||
thread <span class=SpellE>classloader</span> to be set:</p>
|
|
||||||
|
|
||||||
<p class=MsoPlainText><span style='mso-tab-count:1'> </span>Public Class <span
|
<p class=MsoPlainText><span style='mso-tab-count:1'> </span>Public xxx <span
|
||||||
class=SpellE><span class=GramE>getVariantClass</span></span><span class=GramE>(</span>){</p>
|
class=SpellE><span class=GramE>someHandler</span></span><span class=GramE>(</span>Variant[]
|
||||||
|
<span class=SpellE>foo</span>){</p>
|
||||||
|
|
||||||
<p class=MsoPlainText><span style='mso-tab-count:1'> </span><span
|
<p class=MsoPlainText><span style='mso-tab-count:2'> </span><span
|
||||||
style='mso-tab-count:1'> </span><span class=SpellE><span class=GramE>Thread.currentThread</span></span><span
|
class=SpellE><span class=GramE>Thread.currentThread</span></span><span
|
||||||
class=GramE>(</span>).<span class=SpellE>setContextClassLoader</span>(</p>
|
class=GramE>(</span>).<span class=SpellE>setContextClassLoader</span>(</p>
|
||||||
|
|
||||||
<p class=MsoPlainText><span style='mso-tab-count:3'> </span><span
|
<p class=MsoPlainText><span style='mso-tab-count:3'> </span><span
|
||||||
class=SpellE><span class=GramE>this.getClass</span></span><span class=GramE>(</span>).<span
|
class=SpellE><span class=GramE>this.getClass</span></span><span class=GramE>(</span>).<span
|
||||||
class=SpellE>getClassLoader</span>());</p>
|
class=SpellE>getClassLoader</span>());</p>
|
||||||
|
|
||||||
<p class=MsoPlainText><span style='mso-tab-count:1'> </span><span
|
<p class=MsoPlainText><span style='mso-tab-count:2'> </span>// do
|
||||||
style='mso-tab-count:1'> </span><span class=GramE>return</span> <span
|
something</p>
|
||||||
class=SpellE>Variant.class</span></p>
|
|
||||||
|
|
||||||
<p class=MsoPlainText><span style='mso-tab-count:1'> </span>}</p>
|
<p class=MsoPlainText><span style='mso-tab-count:1'> </span>}</p>
|
||||||
|
|
||||||
@@ -276,6 +346,8 @@ class=SpellE>Variant.class</span></p>
|
|||||||
<p class=MsoPlainText>There may still be a dual event queue issue in JWS
|
<p class=MsoPlainText>There may still be a dual event queue issue in JWS
|
||||||
applications that needs to be looked at.</p>
|
applications that needs to be looked at.</p>
|
||||||
|
|
||||||
|
<p class=MsoPlainText><o:p> </o:p></p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
69
docs/HowToBuild.txt
Normal file
69
docs/HowToBuild.txt
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
(2/2005)
|
||||||
|
To build and run:
|
||||||
|
|
||||||
|
Unpack the source archive or check the files out of CVS into d:\jacob
|
||||||
|
|
||||||
|
Install the following tools
|
||||||
|
Microsfot Visual Studio, a stripped down version is available from the MS web site.
|
||||||
|
Eclipse from www.eclipse.org.
|
||||||
|
Java jdk 1.4 (this was built using 1.4.2.06)
|
||||||
|
|
||||||
|
The following configuration was used by most of the development team:
|
||||||
|
JDK = d:\j2sdk1.4.2_06
|
||||||
|
DEST_DIR = d:\jacob
|
||||||
|
MSDEVDIR = d:\apps\\"Microsoft Visual Studio"\VC98
|
||||||
|
|
||||||
|
This project has been converted completely over to ANT. You can
|
||||||
|
run ANT from inside of eclipse or from the command line.
|
||||||
|
The ant process is driven off of a configuration file
|
||||||
|
compilation_tools.properties. Instructions on the information required
|
||||||
|
in that file are contained in build.xml in the root directory.
|
||||||
|
|
||||||
|
Ant, via build.xml will do the following with teh default target.
|
||||||
|
Build the Java code
|
||||||
|
Build the jni code
|
||||||
|
create the dll
|
||||||
|
create jar file
|
||||||
|
|
||||||
|
The package target creates the
|
||||||
|
javadoc and
|
||||||
|
zip files
|
||||||
|
|
||||||
|
ECLIPSE
|
||||||
|
|
||||||
|
Eclipse users will have to do some minor tweaks to their project if they
|
||||||
|
want to use the integrated build process. This is because the unit
|
||||||
|
tests are com.jacob.com files located in the unittest directory while
|
||||||
|
the jacob files themselves are in com.jacob.com off the root directory.
|
||||||
|
(Eventually the the jacob files will be moved to src)
|
||||||
|
Eclipse automatically adds the whole project as a source directory
|
||||||
|
Remove the root of the project from the build path
|
||||||
|
Add folders samples, src and unittest to the build path
|
||||||
|
Exclude *.txt from each of the newly added folders.
|
||||||
|
|
||||||
|
A couple of the samples require a J2EE library in order to compile. This
|
||||||
|
means you'll have to add a J2EE jar file to your classpath. This
|
||||||
|
isn't a problem when using ANT because the Servlet examples are excluded
|
||||||
|
from the build.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- old instructions for makefiles that no longer exist --
|
||||||
|
|
||||||
|
To build:
|
||||||
|
Run VCVARS32 to set up your MS Visual C++ environment
|
||||||
|
cd d:\jacob
|
||||||
|
nmake
|
||||||
|
|
||||||
|
(from dan)I developed this with the C++ compiler and ATL version
|
||||||
|
that ship with VC++ 6.0, so I'm not sure if different versions will
|
||||||
|
work.
|
||||||
|
|
||||||
|
This is currently designed to compile against JDK 1.4.2. The future
|
||||||
|
of the Microsoft SDK is in doubt so support may be discontinued
|
||||||
|
in the future.
|
||||||
|
|
||||||
|
|
||||||
|
The java code is in com\jacob\*.
|
||||||
|
The C++ code is in .\jni.
|
||||||
|
|
||||||
@@ -1,51 +1,51 @@
|
|||||||
<H1>COM Object Lifetime in JACOB</H1>
|
<H1>COM Object Lifetime in JACOB</H1>
|
||||||
<p>
|
<p>
|
||||||
<H2>introduction</H2>
|
<H2>introduction</H2>
|
||||||
<p>
|
<p>
|
||||||
JACOB Version 1.7 implements a new
|
JACOB Version 1.7 implements a new
|
||||||
<a href="JacobThreading.html">Threading Model</a> that is more
|
<a href="JacobThreading.html">Threading Model</a> that is more
|
||||||
compatible with COM apartments. There is also an incompatibility
|
compatible with COM apartments. There is also an incompatibility
|
||||||
between the Java object lifetime model and that of COM objects.
|
between the Java object lifetime model and that of COM objects.
|
||||||
COM Objects live and die by their reference count, whereas Java
|
COM Objects live and die by their reference count, whereas Java
|
||||||
objects are collected by the Garbage Collector (GC) based on algortihms
|
objects are collected by the Garbage Collector (GC) based on algortihms
|
||||||
that are hidden from the user.
|
that are hidden from the user.
|
||||||
<H2>COM Object Lifetime in JACOB Prior to Version 1.7</H2>
|
<H2>COM Object Lifetime in JACOB Prior to Version 1.7</H2>
|
||||||
<p>
|
<p>
|
||||||
In version 1.6 and earlier, JACOB objects which wrapped COM objects
|
In version 1.6 and earlier, JACOB objects which wrapped COM objects
|
||||||
had <code>finalize()</code> methods that would call a native
|
had <code>finalize()</code> methods that would call a native
|
||||||
<code>release</code> method which would call a COM <code>Release</code>.
|
<code>release</code> method which would call a COM <code>Release</code>.
|
||||||
<p>
|
<p>
|
||||||
This has many problems. For one thing, the GC may take a long time to
|
This has many problems. For one thing, the GC may take a long time to
|
||||||
kick in and resource consumption may grow. However, the more problematic
|
kick in and resource consumption may grow. However, the more problematic
|
||||||
issue is that finalizers are called from a separate thread, and, as was
|
issue is that finalizers are called from a separate thread, and, as was
|
||||||
discussed in the <a href="JacobThreading.html">Threading Model</a>
|
discussed in the <a href="JacobThreading.html">Threading Model</a>
|
||||||
document, this can result in COM errors if the object is running in an
|
document, this can result in COM errors if the object is running in an
|
||||||
STA. Even if the object is running in an MTA, the finalizer may decide
|
STA. Even if the object is running in an MTA, the finalizer may decide
|
||||||
to run after we have terminated the thread that holds the component, in
|
to run after we have terminated the thread that holds the component, in
|
||||||
which case we would get fatal errors and crashes.
|
which case we would get fatal errors and crashes.
|
||||||
<H2>COM Object Lifetime in JACOB in Version 1.7</H2>
|
<H2>COM Object Lifetime in JACOB in Version 1.7</H2>
|
||||||
<p>
|
<p>
|
||||||
In Version 1.7, all JACOB objects which wrap COM objects extend
|
In Version 1.7, all JACOB objects which wrap COM objects extend
|
||||||
<code>com.jacob.com.JacobObject</code>. This object has some special
|
<code>com.jacob.com.JacobObject</code>. This object has some special
|
||||||
code to register itself with a <code>com.jacob.com.ROT</code> object
|
code to register itself with a <code>com.jacob.com.ROT</code> object
|
||||||
which represents a Running Object Table (ROT). This table maps a
|
which represents a Running Object Table (ROT). This table maps a
|
||||||
Thread to the set of JacobObjects created in that thread. Therefore,
|
Thread to the set of JacobObjects created in that thread. Therefore,
|
||||||
when you call <code>ComThread.Release()</code>, the ROT checks whether
|
when you call <code>ComThread.Release()</code>, the ROT checks whether
|
||||||
that thread has created any objects, and these objects are released
|
that thread has created any objects, and these objects are released
|
||||||
by calling their native <code>release</code> method (which is public).
|
by calling their native <code>release</code> method (which is public).
|
||||||
<p>
|
<p>
|
||||||
This lifetime management method ties the lifecycle to the thread's
|
This lifetime management method ties the lifecycle to the thread's
|
||||||
lifecycle rather than the GC. The JacobObject's still have finalizers,
|
lifecycle rather than the GC. The JacobObject's still have finalizers,
|
||||||
but they will typically not perform the native <code>release</code>
|
but they will typically not perform the native <code>release</code>
|
||||||
since that has already been called. The native <code>release</code>
|
since that has already been called. The native <code>release</code>
|
||||||
methods were written such that you can call them multiple times without
|
methods were written such that you can call them multiple times without
|
||||||
worrying - since they zero out the native pointer when called the first
|
worrying - since they zero out the native pointer when called the first
|
||||||
time.
|
time.
|
||||||
<p>
|
<p>
|
||||||
If you choose to call <code>release</code> methods on your objects
|
If you choose to call <code>release</code> methods on your objects
|
||||||
yourself, that is allowed. In that case, when the thread is released
|
yourself, that is allowed. In that case, when the thread is released
|
||||||
the release calls will be no-ops.
|
the release calls will be no-ops.
|
||||||
<p>
|
<p>
|
||||||
It becomes important for you to call <code>ComThread.Release()</code>
|
It becomes important for you to call <code>ComThread.Release()</code>
|
||||||
on any thread before you allow it to exit, otherwise you may get
|
on any thread before you allow it to exit, otherwise you may get
|
||||||
some random crashes later on in your code.
|
some random crashes later on in your code.
|
||||||
@@ -1,410 +1,410 @@
|
|||||||
<H1>COM Apartments in JACOB</H1>
|
<H1>COM Apartments in JACOB</H1>
|
||||||
<p>
|
<p>
|
||||||
<H2>introduction</H2>
|
<H2>introduction</H2>
|
||||||
<p>
|
<p>
|
||||||
The COM model for Threading differs from the Java model.
|
The COM model for Threading differs from the Java model.
|
||||||
In COM, each component can declare whether or not it support
|
In COM, each component can declare whether or not it support
|
||||||
multi-threading.
|
multi-threading.
|
||||||
|
|
||||||
You can find some basic information about COM threading at:
|
You can find some basic information about COM threading at:
|
||||||
<p>
|
<p>
|
||||||
<a href="http://www.execpc.com/~gopalan/com/com_threading.html">
|
<a href="http://www.execpc.com/~gopalan/com/com_threading.html">
|
||||||
http://www.execpc.com/~gopalan/com/com_threading.html</a>
|
http://www.execpc.com/~gopalan/com/com_threading.html</a>
|
||||||
<p>
|
<p>
|
||||||
<a href="www.microsoft.com/msj/0297/apartment/apartment.htm">
|
<a href="www.microsoft.com/msj/0297/apartment/apartment.htm">
|
||||||
www.microsoft.com/msj/0297/apartment/apartment.htm</a>
|
www.microsoft.com/msj/0297/apartment/apartment.htm</a>
|
||||||
<p>
|
<p>
|
||||||
<a href="http://www.cswl.com/whiteppr/white/multithreading.html">
|
<a href="http://www.cswl.com/whiteppr/white/multithreading.html">
|
||||||
http://www.cswl.com/whiteppr/white/multithreading.html
|
http://www.cswl.com/whiteppr/white/multithreading.html
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>
|
||||||
The term <b>Single Threaded Apartment (STA)</b> refers to a thread
|
The term <b>Single Threaded Apartment (STA)</b> refers to a thread
|
||||||
where all COM objects created in that thread are
|
where all COM objects created in that thread are
|
||||||
single-threaded. This can manifest itself in two ways:
|
single-threaded. This can manifest itself in two ways:
|
||||||
<br>
|
<br>
|
||||||
Either all calls into that component are made from the same thread
|
Either all calls into that component are made from the same thread
|
||||||
that created the component
|
that created the component
|
||||||
<br>
|
<br>
|
||||||
OR any call that is made from another thread gets serialized by COM.
|
OR any call that is made from another thread gets serialized by COM.
|
||||||
This serialization of calls is done by using a Windows message loop and
|
This serialization of calls is done by using a Windows message loop and
|
||||||
posting messages to a hidden window (I'm not kidding). The way COM
|
posting messages to a hidden window (I'm not kidding). The way COM
|
||||||
achieves this is by requiring any other thread to make calls through
|
achieves this is by requiring any other thread to make calls through
|
||||||
a local Proxy object rather than the original object (more on this
|
a local Proxy object rather than the original object (more on this
|
||||||
when we discuss the JACOB DispatchProxy class).
|
when we discuss the JACOB DispatchProxy class).
|
||||||
<p>
|
<p>
|
||||||
What does this mean for a Java application? If you are using a component
|
What does this mean for a Java application? If you are using a component
|
||||||
that declares itself as <b>ThreadingModel "Apartment"</b> (you can
|
that declares itself as <b>ThreadingModel "Apartment"</b> (you can
|
||||||
find this out by looking in the registry under its CLSID), and you plan
|
find this out by looking in the registry under its CLSID), and you plan
|
||||||
to create, use and destroy this component in one thread - then you are
|
to create, use and destroy this component in one thread - then you are
|
||||||
following the rules of an STA and you can declare the thread as an
|
following the rules of an STA and you can declare the thread as an
|
||||||
STA thread.
|
STA thread.
|
||||||
<p>
|
<p>
|
||||||
On the other hand, if you need to make method calls from another thread
|
On the other hand, if you need to make method calls from another thread
|
||||||
(e.g. in a servlet) then you have a few choices. Either you
|
(e.g. in a servlet) then you have a few choices. Either you
|
||||||
create the component in its own STA, by extending
|
create the component in its own STA, by extending
|
||||||
<code>com.jacob.com.STA</code>, and use the
|
<code>com.jacob.com.STA</code>, and use the
|
||||||
<code>com.jacob.com.DispatchProxy</code> class to pass the Dispatch
|
<code>com.jacob.com.DispatchProxy</code> class to pass the Dispatch
|
||||||
pointer between threads, or you can declare your thread as an MTA
|
pointer between threads, or you can declare your thread as an MTA
|
||||||
thread. In that case, COM will make
|
thread. In that case, COM will make
|
||||||
the cross-thread calls into the STA that is running your component.
|
the cross-thread calls into the STA that is running your component.
|
||||||
If you create an Apartment threaded component in the MTA,
|
If you create an Apartment threaded component in the MTA,
|
||||||
COM will automatically create an STA for you and put your
|
COM will automatically create an STA for you and put your
|
||||||
component in there, and then marshall all the calls.
|
component in there, and then marshall all the calls.
|
||||||
<p>
|
<p>
|
||||||
This brings us to the notion of a <b>Main STA</b>. COM requires that
|
This brings us to the notion of a <b>Main STA</b>. COM requires that
|
||||||
if there is any Apartment threaded component in your application, then
|
if there is any Apartment threaded component in your application, then
|
||||||
the first STA created is tagged as the <b>Main STA</b>. COM uses the
|
the first STA created is tagged as the <b>Main STA</b>. COM uses the
|
||||||
Main STA to create all the Apartment threaded components that are
|
Main STA to create all the Apartment threaded components that are
|
||||||
created from an MTA thread. The problem is that if you have already
|
created from an MTA thread. The problem is that if you have already
|
||||||
created an STA, then COM will pick that as the Main STA, and if you
|
created an STA, then COM will pick that as the Main STA, and if you
|
||||||
ever exit that thread - the whole application will exit.
|
ever exit that thread - the whole application will exit.
|
||||||
|
|
||||||
<H2>COM Threads in JACOB Prior to Version 1.7</H2>
|
<H2>COM Threads in JACOB Prior to Version 1.7</H2>
|
||||||
<p>
|
<p>
|
||||||
Up until version 1.7 of JACOB, there was only one model available
|
Up until version 1.7 of JACOB, there was only one model available
|
||||||
in JACOB:
|
in JACOB:
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
Before version 1.6: All threads were automatically initialized as STAs.
|
Before version 1.6: All threads were automatically initialized as STAs.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
In version 1.6: All threads were automatically initialized as MTAs.
|
In version 1.6: All threads were automatically initialized as MTAs.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
The reason for the change in default was that tagging a Java thread
|
The reason for the change in default was that tagging a Java thread
|
||||||
as an STA can cause problems. Any Java Swing application, as well as
|
as an STA can cause problems. Any Java Swing application, as well as
|
||||||
servlets and applets need to be able to make calls from multiple
|
servlets and applets need to be able to make calls from multiple
|
||||||
threads. If you try to make COM method calls across STA threads - it
|
threads. If you try to make COM method calls across STA threads - it
|
||||||
will fail!
|
will fail!
|
||||||
<p>
|
<p>
|
||||||
In most cases, the default chosen by JACOB 1.6 (MTA) works fine, however
|
In most cases, the default chosen by JACOB 1.6 (MTA) works fine, however
|
||||||
there are some notable exceptions that have caused people grief. One
|
there are some notable exceptions that have caused people grief. One
|
||||||
such exception is in the case of MAPI. It turns out that if you try to
|
such exception is in the case of MAPI. It turns out that if you try to
|
||||||
create a MAPI object from an MTA thread - it simply fails and exits.
|
create a MAPI object from an MTA thread - it simply fails and exits.
|
||||||
This has caused some people to recompile JACOB 1.6 back with the STA
|
This has caused some people to recompile JACOB 1.6 back with the STA
|
||||||
default.
|
default.
|
||||||
<p>
|
<p>
|
||||||
There is another problem with MTA threads: when you are using Apartment
|
There is another problem with MTA threads: when you are using Apartment
|
||||||
threaded components, we already noted that COM will create the
|
threaded components, we already noted that COM will create the
|
||||||
components in the Main STA. If one doesn't exist, COM will create it.
|
components in the Main STA. If one doesn't exist, COM will create it.
|
||||||
However, this means that <b>all</b> Apartment threaded components will
|
However, this means that <b>all</b> Apartment threaded components will
|
||||||
be created in the <b>same STA</b>. This creates a bottleneck, and a
|
be created in the <b>same STA</b>. This creates a bottleneck, and a
|
||||||
dependency between unrelated components. Also, if that STA exits, then
|
dependency between unrelated components. Also, if that STA exits, then
|
||||||
all components are destroyed and the application will likely crash.
|
all components are destroyed and the application will likely crash.
|
||||||
|
|
||||||
<H2>COM Threads in JACOB Version 1.7</H2>
|
<H2>COM Threads in JACOB Version 1.7</H2>
|
||||||
<p>
|
<p>
|
||||||
In Version 1.7 we have added finer grained control to allow the
|
In Version 1.7 we have added finer grained control to allow the
|
||||||
Java programmer to control how COM creates its components.
|
Java programmer to control how COM creates its components.
|
||||||
Unfortunately, this means that you need to have a pretty good
|
Unfortunately, this means that you need to have a pretty good
|
||||||
understanding of the dark and mystical subject of COM Apartments.
|
understanding of the dark and mystical subject of COM Apartments.
|
||||||
There are a few different cases you need to consider:
|
There are a few different cases you need to consider:
|
||||||
<H3>Default</H3>
|
<H3>Default</H3>
|
||||||
<p>
|
<p>
|
||||||
If you simply run code that was created in Version 1.6 and ignore
|
If you simply run code that was created in Version 1.6 and ignore
|
||||||
the COM threading issue, then you will get the same behavior as in 1.6:
|
the COM threading issue, then you will get the same behavior as in 1.6:
|
||||||
Each java thread will be an MTA thread, and all Apartment threaded
|
Each java thread will be an MTA thread, and all Apartment threaded
|
||||||
components will be created by COM in its own Main STA. This typically
|
components will be created by COM in its own Main STA. This typically
|
||||||
works for most applications (exceptions noted above).
|
works for most applications (exceptions noted above).
|
||||||
<H3>Create Your Own Apartment</H3>
|
<H3>Create Your Own Apartment</H3>
|
||||||
<p>
|
<p>
|
||||||
To declare an MTA thread use the following template:
|
To declare an MTA thread use the following template:
|
||||||
<br>
|
<br>
|
||||||
<pre>
|
<pre>
|
||||||
<code>
|
<code>
|
||||||
ComThread.InitMTA();
|
ComThread.InitMTA();
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
</pre>
|
</pre>
|
||||||
</code>
|
</code>
|
||||||
<br>
|
<br>
|
||||||
If you want JACOB to create its own Main STA (rather than having COM
|
If you want JACOB to create its own Main STA (rather than having COM
|
||||||
choose an STA for you), then you should use:
|
choose an STA for you), then you should use:
|
||||||
<br>
|
<br>
|
||||||
<code>
|
<code>
|
||||||
<pre>
|
<pre>
|
||||||
Thread 1:
|
Thread 1:
|
||||||
ComThread.InitMTA(true); // a true tells JACOB to create a Main STA
|
ComThread.InitMTA(true); // a true tells JACOB to create a Main STA
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
...
|
...
|
||||||
Thread 2:
|
Thread 2:
|
||||||
ComThread.InitMTA();
|
ComThread.InitMTA();
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
ComThread.quitMainSTA();
|
ComThread.quitMainSTA();
|
||||||
</pre>
|
</pre>
|
||||||
</code>
|
</code>
|
||||||
<br>
|
<br>
|
||||||
In this case, you can also create the Main STA explicitly:
|
In this case, you can also create the Main STA explicitly:
|
||||||
<br>
|
<br>
|
||||||
<code>
|
<code>
|
||||||
<pre>
|
<pre>
|
||||||
ComThread.startMainSTA();
|
ComThread.startMainSTA();
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
Thread 1:
|
Thread 1:
|
||||||
ComThread.InitMTA();
|
ComThread.InitMTA();
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
...
|
...
|
||||||
Thread 2:
|
Thread 2:
|
||||||
ComThread.InitMTA();
|
ComThread.InitMTA();
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
ComThread.quitMainSTA();
|
ComThread.quitMainSTA();
|
||||||
</pre>
|
</pre>
|
||||||
</code>
|
</code>
|
||||||
<br>
|
<br>
|
||||||
In the latter case, all Apartment threaded components will be created in
|
In the latter case, all Apartment threaded components will be created in
|
||||||
JACOB's main STA. This still has all the problems of components
|
JACOB's main STA. This still has all the problems of components
|
||||||
sharing the same Main STA and creating a bottleneck. To avoid that,
|
sharing the same Main STA and creating a bottleneck. To avoid that,
|
||||||
you can also create STA threads yourself:
|
you can also create STA threads yourself:
|
||||||
<br>
|
<br>
|
||||||
<code>
|
<code>
|
||||||
<pre>
|
<pre>
|
||||||
ComThread.startMainSTA();
|
ComThread.startMainSTA();
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
Thread 1:
|
Thread 1:
|
||||||
ComThread.InitSTA();
|
ComThread.InitSTA();
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
...
|
...
|
||||||
Thread 2:
|
Thread 2:
|
||||||
ComThread.InitMTA();
|
ComThread.InitMTA();
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
ComThread.quitMainSTA();
|
ComThread.quitMainSTA();
|
||||||
</pre>
|
</pre>
|
||||||
</code>
|
</code>
|
||||||
<br>
|
<br>
|
||||||
In this example, thread 1 is an STA and thread 2 is an MTA. You could
|
In this example, thread 1 is an STA and thread 2 is an MTA. You could
|
||||||
omit the call to ComThread.startMainSTA(), but if you do, then COM will
|
omit the call to ComThread.startMainSTA(), but if you do, then COM will
|
||||||
make the first STA your main one, and then if you exit that thread,
|
make the first STA your main one, and then if you exit that thread,
|
||||||
the application will crash.
|
the application will crash.
|
||||||
<p>
|
<p>
|
||||||
Actually, Thread 1 is <i>almost</i> an STA. It's lacking a windows
|
Actually, Thread 1 is <i>almost</i> an STA. It's lacking a windows
|
||||||
message loop. So, this type of STA is fine as long as you are creating
|
message loop. So, this type of STA is fine as long as you are creating
|
||||||
a component and using it in the same thread, and not makind event
|
a component and using it in the same thread, and not makind event
|
||||||
callbacks.
|
callbacks.
|
||||||
<H3>JACOB's STA Class</H3>
|
<H3>JACOB's STA Class</H3>
|
||||||
<p>
|
<p>
|
||||||
If you want to create an true STA where you can create a component and
|
If you want to create an true STA where you can create a component and
|
||||||
then let other threads call methods on it, then you need a windows
|
then let other threads call methods on it, then you need a windows
|
||||||
message loop. JACOB provides a class called:
|
message loop. JACOB provides a class called:
|
||||||
<code>com.jacob.com.STA</code> which does exactly this.
|
<code>com.jacob.com.STA</code> which does exactly this.
|
||||||
<code>
|
<code>
|
||||||
<pre>
|
<pre>
|
||||||
public class com.jacob.com.STA extends java.lang.Thread
|
public class com.jacob.com.STA extends java.lang.Thread
|
||||||
{
|
{
|
||||||
public com.jacob.com.STA();
|
public com.jacob.com.STA();
|
||||||
public boolean OnInit(); // you override this
|
public boolean OnInit(); // you override this
|
||||||
public void OnQuit(); // you override this
|
public void OnQuit(); // you override this
|
||||||
public void quit(); // you can call this from ANY thread
|
public void quit(); // you can call this from ANY thread
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</code>
|
</code>
|
||||||
<p>
|
<p>
|
||||||
The STA class extends
|
The STA class extends
|
||||||
<code>java.lang.Thread</code> and it provides you with two methods
|
<code>java.lang.Thread</code> and it provides you with two methods
|
||||||
that you can override: <code>OnInit</code> and <code>OnQuit</code>.
|
that you can override: <code>OnInit</code> and <code>OnQuit</code>.
|
||||||
These methods are called from the thread's <code>run</code> method
|
These methods are called from the thread's <code>run</code> method
|
||||||
so they will execute in the new thread. These methods allow you to
|
so they will execute in the new thread. These methods allow you to
|
||||||
create COM components (Dispatch objects) and release them.
|
create COM components (Dispatch objects) and release them.
|
||||||
To create an STA, you subclass it and override the OnInit.
|
To create an STA, you subclass it and override the OnInit.
|
||||||
<p>
|
<p>
|
||||||
The <code>quit</code> method is the <b>only</b> other method that
|
The <code>quit</code> method is the <b>only</b> other method that
|
||||||
can be called from any thread. This method uses the Win32 function
|
can be called from any thread. This method uses the Win32 function
|
||||||
<code>PostThreadMessage</code> to force the STA's windows message loop
|
<code>PostThreadMessage</code> to force the STA's windows message loop
|
||||||
to exit, thereby terminating the thread.
|
to exit, thereby terminating the thread.
|
||||||
<p>
|
<p>
|
||||||
You will then need to make calls into the component that is running
|
You will then need to make calls into the component that is running
|
||||||
in the STA thread. If you simply try to make calls from another thread
|
in the STA thread. If you simply try to make calls from another thread
|
||||||
on a Dispatch object created in the STA thread, you will get a COM
|
on a Dispatch object created in the STA thread, you will get a COM
|
||||||
Exception. For more details see:
|
Exception. For more details see:
|
||||||
<a href="http://www.develop.com/effectivecom">
|
<a href="http://www.develop.com/effectivecom">
|
||||||
Don Box 'Effective COM' Rule 29</a>: Don't Access raw
|
Don Box 'Effective COM' Rule 29</a>: Don't Access raw
|
||||||
interface pointers across apartment boundaries.
|
interface pointers across apartment boundaries.
|
||||||
<H3>The DispatchProxy Class</H3>
|
<H3>The DispatchProxy Class</H3>
|
||||||
Since you cannot call methods directly on a Dispatch object created
|
Since you cannot call methods directly on a Dispatch object created
|
||||||
in another STA JACOB provides a method for the class that created
|
in another STA JACOB provides a method for the class that created
|
||||||
the Dispatch object to marshal it to your thread. This is done via
|
the Dispatch object to marshal it to your thread. This is done via
|
||||||
the <code>com.jacob.com.DispatchProxy</code> class.
|
the <code>com.jacob.com.DispatchProxy</code> class.
|
||||||
<code>
|
<code>
|
||||||
<pre>
|
<pre>
|
||||||
public class DispatchProxy extends JacobObject {
|
public class DispatchProxy extends JacobObject {
|
||||||
public DispatchProxy(Dispatch);
|
public DispatchProxy(Dispatch);
|
||||||
public Dispatch toDispatch();
|
public Dispatch toDispatch();
|
||||||
|
|
||||||
public native void release();
|
public native void release();
|
||||||
public void finalize();
|
public void finalize();
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
This class works as follows: the thread that created the Dispatch
|
This class works as follows: the thread that created the Dispatch
|
||||||
object constructs an instance of DispatchProxy(Dispatch) with the
|
object constructs an instance of DispatchProxy(Dispatch) with the
|
||||||
Dispatch as a parameter. This instance can then be accessed from
|
Dispatch as a parameter. This instance can then be accessed from
|
||||||
another thread, which will invoke its <code>toDispatch</code> method
|
another thread, which will invoke its <code>toDispatch</code> method
|
||||||
proxy as if it were local to your thread. COM will do the inter-thread
|
proxy as if it were local to your thread. COM will do the inter-thread
|
||||||
marshalling transparently.
|
marshalling transparently.
|
||||||
<p>
|
<p>
|
||||||
The following example is part of samples/test/ScriptTest2.java in the
|
The following example is part of samples/test/ScriptTest2.java in the
|
||||||
JACOB distribution. It shows how you can create the ScriptControl
|
JACOB distribution. It shows how you can create the ScriptControl
|
||||||
in one STA thread and make method calls on it from another:
|
in one STA thread and make method calls on it from another:
|
||||||
<code>
|
<code>
|
||||||
<pre>
|
<pre>
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
import com.jacob.activeX.*;
|
import com.jacob.activeX.*;
|
||||||
|
|
||||||
class ScriptTest2 extends STA
|
class ScriptTest2 extends STA
|
||||||
{
|
{
|
||||||
public static ActiveXComponent sC;
|
public static ActiveXComponent sC;
|
||||||
public static Dispatch sControl = null;
|
public static Dispatch sControl = null;
|
||||||
public static DispatchProxy sCon = null;
|
public static DispatchProxy sCon = null;
|
||||||
|
|
||||||
public boolean OnInit()
|
public boolean OnInit()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.out.println("OnInit");
|
System.out.println("OnInit");
|
||||||
System.out.println(Thread.currentThread());
|
System.out.println(Thread.currentThread());
|
||||||
String lang = "VBScript";
|
String lang = "VBScript";
|
||||||
|
|
||||||
sC = new ActiveXComponent("ScriptControl");
|
sC = new ActiveXComponent("ScriptControl");
|
||||||
sControl = (Dispatch)sC.getObject();
|
sControl = (Dispatch)sC.getObject();
|
||||||
|
|
||||||
// sCon can be called from another thread
|
// sCon can be called from another thread
|
||||||
sCon = new DispatchProxy(sControl);
|
sCon = new DispatchProxy(sControl);
|
||||||
|
|
||||||
Dispatch.put(sControl, "Language", lang);
|
Dispatch.put(sControl, "Language", lang);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnQuit()
|
public void OnQuit()
|
||||||
{
|
{
|
||||||
System.out.println("OnQuit");
|
System.out.println("OnQuit");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String args[]) throws Exception
|
public static void main(String args[]) throws Exception
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
ComThread.InitSTA();
|
ComThread.InitSTA();
|
||||||
ScriptTest2 script = new ScriptTest2();
|
ScriptTest2 script = new ScriptTest2();
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
|
|
||||||
// get a thread-local Dispatch from sCon
|
// get a thread-local Dispatch from sCon
|
||||||
Dispatch sc = sCon.toDispatch();
|
Dispatch sc = sCon.toDispatch();
|
||||||
|
|
||||||
// call a method on the thread-local Dispatch obtained
|
// call a method on the thread-local Dispatch obtained
|
||||||
// from the DispatchProxy. If you try to make the same
|
// from the DispatchProxy. If you try to make the same
|
||||||
// method call on the sControl object - you will get a
|
// method call on the sControl object - you will get a
|
||||||
// ComException.
|
// ComException.
|
||||||
Variant result = Dispatch.call(sc, "Eval", args[0]);
|
Variant result = Dispatch.call(sc, "Eval", args[0]);
|
||||||
System.out.println("eval("+args[0]+") = "+ result);
|
System.out.println("eval("+args[0]+") = "+ result);
|
||||||
script.quit();
|
script.quit();
|
||||||
System.out.println("called quit");
|
System.out.println("called quit");
|
||||||
} catch (ComException e) {
|
} catch (ComException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</code>
|
</code>
|
||||||
<p>
|
<p>
|
||||||
You can try to modify the <code>Dispatch.call</code> invocation in
|
You can try to modify the <code>Dispatch.call</code> invocation in
|
||||||
the main thread to use <code>sControl</code> directly, and you will see
|
the main thread to use <code>sControl</code> directly, and you will see
|
||||||
that it fails. Notice that once we construct the ScriptTest2 object
|
that it fails. Notice that once we construct the ScriptTest2 object
|
||||||
in the main thread, we sleep for a second to allow the other thread
|
in the main thread, we sleep for a second to allow the other thread
|
||||||
time to initialize itself.
|
time to initialize itself.
|
||||||
<p>
|
<p>
|
||||||
The STA thread calls <code>sCon = new DispatchProxy(sControl);</code>
|
The STA thread calls <code>sCon = new DispatchProxy(sControl);</code>
|
||||||
to save a global reference to the DispatchProxy that represents the
|
to save a global reference to the DispatchProxy that represents the
|
||||||
<code>sControl</code> object. The main thread then calls:
|
<code>sControl</code> object. The main thread then calls:
|
||||||
<code>Dispatch sc = sCon.toDispatch();</code> to get a local Dispatch
|
<code>Dispatch sc = sCon.toDispatch();</code> to get a local Dispatch
|
||||||
proxy out of the DispatchProxy object.
|
proxy out of the DispatchProxy object.
|
||||||
<p>
|
<p>
|
||||||
At most <b>one(!)</b>
|
At most <b>one(!)</b>
|
||||||
thread can call toDispatch(), and the call can be made only once.
|
thread can call toDispatch(), and the call can be made only once.
|
||||||
This is because a IStream object is used to pass the proxy, and
|
This is because a IStream object is used to pass the proxy, and
|
||||||
it is only written once and closed when you read it.
|
it is only written once and closed when you read it.
|
||||||
If you need multiple threads to access a Dispatch pointer, then
|
If you need multiple threads to access a Dispatch pointer, then
|
||||||
create that many DispatchProxy objects. For more details please
|
create that many DispatchProxy objects. For more details please
|
||||||
refer to the Don Box reference above.
|
refer to the Don Box reference above.
|
||||||
|
|
||||||
|
|
||||||
<H3>Recommended Procedure</H3>
|
<H3>Recommended Procedure</H3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
It is recommended that you always allow JACOB to manage the main STA
|
It is recommended that you always allow JACOB to manage the main STA
|
||||||
rather than letting COM create one on its own or tag one of yours.
|
rather than letting COM create one on its own or tag one of yours.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Declare an STA thread using ComThread.InitSTA()
|
Declare an STA thread using ComThread.InitSTA()
|
||||||
if all your
|
if all your
|
||||||
method calls for that component are going to come from the same thread.
|
method calls for that component are going to come from the same thread.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
If you want an STA thread that allows other threads to call into it,
|
If you want an STA thread that allows other threads to call into it,
|
||||||
use the <code>com.jacob.com.STA</code> class as outlined above.
|
use the <code>com.jacob.com.STA</code> class as outlined above.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
If you have a COM component that declares its ThreadingModel as
|
If you have a COM component that declares its ThreadingModel as
|
||||||
"Free" or "Both", then use the MTA.
|
"Free" or "Both", then use the MTA.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
In most cases, if you need to make method calls from multiple threads,
|
In most cases, if you need to make method calls from multiple threads,
|
||||||
you can simply
|
you can simply
|
||||||
use MTA threads, and allow COM to create the components in
|
use MTA threads, and allow COM to create the components in
|
||||||
the Main STA. You should only create your own STA's and DispatchProxy
|
the Main STA. You should only create your own STA's and DispatchProxy
|
||||||
if you understand COM well enough to know when the MTA solution
|
if you understand COM well enough to know when the MTA solution
|
||||||
will fail or have other shortcomings.
|
will fail or have other shortcomings.
|
||||||
<p>
|
<p>
|
||||||
There are 3 examples in the samples/test directory that demonstrate
|
There are 3 examples in the samples/test directory that demonstrate
|
||||||
these cases:
|
these cases:
|
||||||
<p>
|
<p>
|
||||||
ScriptTest.java - creates an STA for the ScriptControl component and
|
ScriptTest.java - creates an STA for the ScriptControl component and
|
||||||
runs all its method calls from that STA.
|
runs all its method calls from that STA.
|
||||||
<p>
|
<p>
|
||||||
ScriptTest2.java - creates a separate STA thread, and makes
|
ScriptTest2.java - creates a separate STA thread, and makes
|
||||||
method calls into the component from another thread using DispatchProxy.
|
method calls into the component from another thread using DispatchProxy.
|
||||||
<p>
|
<p>
|
||||||
ScriptTest3.java - creates a separate MTA thread, and makes method
|
ScriptTest3.java - creates a separate MTA thread, and makes method
|
||||||
calls into the component from another MTA thread. This is simpler
|
calls into the component from another MTA thread. This is simpler
|
||||||
than ScriptTest2 for most applications.
|
than ScriptTest2 for most applications.
|
||||||
<p>
|
<p>
|
||||||
<h3>Default Threading Model</h3>
|
<h3>Default Threading Model</h3>
|
||||||
If you create a new thread, and don't call
|
If you create a new thread, and don't call
|
||||||
<code>ComThread.InitSTA()</code> or <code>ComThread.InitMTA()</code>
|
<code>ComThread.InitSTA()</code> or <code>ComThread.InitMTA()</code>
|
||||||
on it, then the first time your java code creates a JacobObject, it
|
on it, then the first time your java code creates a JacobObject, it
|
||||||
will try to register itself with the ROT, and when it sees that the
|
will try to register itself with the ROT, and when it sees that the
|
||||||
current thread is not initialized, it will initialize it as MTA.
|
current thread is not initialized, it will initialize it as MTA.
|
||||||
This means that the code to do this is no longer inside the native
|
This means that the code to do this is no longer inside the native
|
||||||
jni code - it is now in the <code>com.jacob.com.ROT</code> class.
|
jni code - it is now in the <code>com.jacob.com.ROT</code> class.
|
||||||
For more details on the ROT, see the
|
For more details on the ROT, see the
|
||||||
<a href="JacobComLifetime.html">Object Lifetime</a> document.
|
<a href="JacobComLifetime.html">Object Lifetime</a> document.
|
||||||
344
docs/WhatsNew.html
Normal file
344
docs/WhatsNew.html
Normal file
@@ -0,0 +1,344 @@
|
|||||||
|
<h1>What's New in JACOB 1.9</H1>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Event Callbacks</b>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>Variant parameters can now be modified by the receiver to be passed
|
||||||
|
back to the COM caller </li>
|
||||||
|
<li>Callbacks can now be received when running in JWS other launchers where
|
||||||
|
JACOB.jar is not in the system classloader's path.</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Dispatch API Clarifications</B>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>All static method's first parameters have been more strongly typed
|
||||||
|
to the Dispatch class, rather than Object. This may call for code
|
||||||
|
changes in the cases of code that just asigned Dispatch objects
|
||||||
|
to variables of type Object rather than Dispatch or one of its subclasses </li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Dispatch subclasses are now supported with pointer modifying constructor</b>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>Dispatch and ActiveXComponent now includes a constructor to be used by Dispatch subclasses
|
||||||
|
that swaps the pointers around. This eliminates the need for every Dispatch subclass
|
||||||
|
to have a constructor that swapped and nulled out the pointers to the COM layer.
|
||||||
|
All samples have updated to use the new api </li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>ActiveXComponent has been upgraded</b><ul>
|
||||||
|
|
||||||
|
<li>ActiveXComponent methods return ActiveXComponets </li>
|
||||||
|
<li>Methods have been added to the ActiveXComponents to retrieve
|
||||||
|
parameters as Dispatch objects or ActiveX components. The
|
||||||
|
Script Tests have been updated to show the same programs in Dispatch
|
||||||
|
format or ActiveXComponentFormat </li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Memory Management</b>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>Beta test option that lets an application use automatic object object
|
||||||
|
removal through the use of weak reference hash maps in the ROT class. The
|
||||||
|
default behavior of manual release via the COMThread class has been retained as
|
||||||
|
the default behavior. Developers can test automatic memory collection by
|
||||||
|
using the command line option <i>-Dcom.JACOB.autogc=true</i> </li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>JNI Changes</b>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>Erroneous Array dimension checking fixed for certain boolean set and get functions
|
||||||
|
</li>
|
||||||
|
<li>Alternative method for finding Variant class for callbacks in JWS
|
||||||
|
or other application lanchers where the system classloader does not
|
||||||
|
know about JACOB classes. </li>
|
||||||
|
<li>Unicode is supported for putString and putStringRef</li>
|
||||||
|
<li>EventProxy zeros out the com object reference in the Variant objects
|
||||||
|
that are created by EventProxy so that they are not double released,
|
||||||
|
by both the Java VM and calling code from the COM side. The caller
|
||||||
|
is supposed to be responsible for releasing the memory it created.
|
||||||
|
This fix only applies to Variants created in callbacks. </li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Logging Additions</b><ul>
|
||||||
|
|
||||||
|
<li>Debugging logging to standard out for JACOB can be turned on by using the
|
||||||
|
command line option <i>-Dcom.JACOB.debug=true</i></li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Visual Studio</b><ul>
|
||||||
|
|
||||||
|
<li>The VisualStudio directory in the CVS repository will be removed in the next
|
||||||
|
release</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Documentation</b><ul>
|
||||||
|
|
||||||
|
<li>API documentation via Javadoc is now being generated for all classes.</li>
|
||||||
|
|
||||||
|
<li>The development team is looking for help in upgrading the quality of the
|
||||||
|
class documentation</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Build Changes</b>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>A static method has been added to JacobObject that returns the build version</li>
|
||||||
|
|
||||||
|
<li>The project is now being built using ANT. Most of the developers are
|
||||||
|
running this from inside of Eclipse</li>
|
||||||
|
<li>All makefiles have been purged</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Tracked Changes</h2>
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td width="100%" colspan="2"><b>Bugs</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1116101</td>
|
||||||
|
<td width="87%">jacob-msg 0284 : Access Violation while garbage collecting</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1114159</td>
|
||||||
|
<td width="87%">Problem with COM Error Trapping in JACOB DLL</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1113610</td>
|
||||||
|
<td width="87%">Bad error check in SafeArray.cpp</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1066698</td>
|
||||||
|
<td width="87%">Minor Memory leak in Dispatch.cpp</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1065533</td>
|
||||||
|
<td width="87%">Problem with unicode conversion</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1053871</td>
|
||||||
|
<td width="87%">solution for memory leak in 1.7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1053870</td>
|
||||||
|
<td width="87%">JACOB0msg 2019 - Safe Array</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1053866</td>
|
||||||
|
<td width="87%">getHResult only returns 80020009</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">960646</td>
|
||||||
|
<td width="87%">But in SafeArray:: getBoolean for 2D arrays</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%"> </td>
|
||||||
|
<td width="87%"> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="100%" colspan="2"><b>Patches</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1115187</td>
|
||||||
|
<td width="87%">EventCallbacks fail w/Variant ClassNotFoundException in JWS</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1105915</td>
|
||||||
|
<td width="87%">Fix for event handling memory corruption</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1090104</td>
|
||||||
|
<td width="87%">Weak Reference in teh ROT</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1068544</td>
|
||||||
|
<td width="87%">in/out parameter support for event handlers</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">981540</td>
|
||||||
|
<td width="87%">jre 1.4.2 fix as patch</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%"> </td>
|
||||||
|
<td width="87%"> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="100%" colspan="2"><b>Feature Requests</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1049390</td>
|
||||||
|
<td width="87%">static Version information</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1049224</td>
|
||||||
|
<td width="87%">Javadocs or at least script to generate it</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%">1049158</td>
|
||||||
|
<td width="87%">API to get ProgId of ActiveXComponent</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%"> </td>
|
||||||
|
<td width="87%"> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h1>What's New in JACOB 1.8</H1>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Move To SourceForge</b>
|
||||||
|
The project is not housed at
|
||||||
|
<a href="http://sourceforge.net/projects/jacob-project/">Sourceforge.net</a>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Licensing Change</b>
|
||||||
|
All limitations on commercial use of JACOB have been removed and it
|
||||||
|
is now being developed under a BSD license at
|
||||||
|
<a href="http://sourceforge.net/projects/jacob-project/">Sourceforge.net</a>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Compiled with Java 1.4.2</b>
|
||||||
|
Version 1.8 was compiled with JSEE 1.4.2 and fixes the compilation bug
|
||||||
|
that was remnant of compilation with JDK 1.1.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Baseline For Change</b>
|
||||||
|
This version is the baseline for the first CVS checkin and we encourage
|
||||||
|
people to start contributing to the project with this version.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<h1>What's New in JACOB 1.7</H1>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Explicit COM Threading Model Support:</b>
|
||||||
|
See a detailed discussion of
|
||||||
|
<a href="JacobThreading.html">COM Apartments in JACOB</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>New COM Object Lifetime model:</b>
|
||||||
|
See a detailed discussion of
|
||||||
|
<a href="JacobComLifetime.html">COM Object Lifetime in JACOB</a>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Improved Event Handling:</b>
|
||||||
|
Thanks to code contributed by
|
||||||
|
<a href="mailto:n.o.bouvin@daimi.au.dk">
|
||||||
|
Niels Olof Bouvin</a>
|
||||||
|
and <a href="mailto:jehoej@daimi.au.dk">Henning Jae</a> JACOB 1.7 can
|
||||||
|
read the type information of a Connection Point interface by looking
|
||||||
|
it up in the registry. This makes it possible to use events with IE as
|
||||||
|
well as office products.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Improved Dispatch:</b>
|
||||||
|
Error messages from Invoke failures are now printed out as well as
|
||||||
|
allowing the passing in of arguments to a Get method.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>EnumVariant Implementation:</b>
|
||||||
|
Makes it easier to iterate over COM collections. Thanks to code
|
||||||
|
contributed by
|
||||||
|
<a href="mailto:Thomas.Hallgren@eoncompany.com">Thomas Hallgren</a>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>SafeArray leaks:</b>
|
||||||
|
SafeArrays were not being properly freed prior to version 1.7, many
|
||||||
|
other memory leaks were fixed as well.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>Visual Studio Project:</b>
|
||||||
|
For those who want to debug: vstudio/JACOB. At the moment all the
|
||||||
|
native code is replicated there from the jni directory...
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
<H1>Related Links</H1>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
The JACOB mailing list is hosted at yahoo groups:
|
||||||
|
<a href="http://groups.yahoo.com/group/jacob-project">
|
||||||
|
http://groups.yahoo.com/group/JACOB-project</a>.
|
||||||
|
<b>This is the preferred way to get support for JACOB</b>. It also
|
||||||
|
includes an extensive archive. If you are doing any development with
|
||||||
|
JACOB, please join the list.
|
||||||
|
<li>
|
||||||
|
Massimiliano Bigatti has developed
|
||||||
|
<a href="http://www.bigatti.it/projects/jacobgen/">
|
||||||
|
JACOBgen - a generator that automatically creates JACOB code from
|
||||||
|
Type Libraries</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Steven Lewis is developing a version of Java2Com that supports JACOB
|
||||||
|
code generation. See:
|
||||||
|
<a href="http://www.lordjoe.com/Java2Com/index.html">
|
||||||
|
http://www.lordjoe.com/Java2Com/index.html</a>.
|
||||||
|
<li>
|
||||||
|
To find documentation on the com.ms.com package, go to:
|
||||||
|
<a href="http://www.microsoft.com/java/download/dl_sdk40.htm">
|
||||||
|
http://www.microsoft.com/java/download/dl_sdk40.htm</a>
|
||||||
|
and at the bottom of the page is a link that says:
|
||||||
|
Microsoft SDK for Java 4.0 Documentation Only. You should download
|
||||||
|
that file and install it. Then, view sdkdocs.chm and look for
|
||||||
|
"Microsoft Packages Reference". Hopefully, the next release of
|
||||||
|
JACOB will include full javadoc (volunteers?)...</li>
|
||||||
3
docs/todo.txt
Normal file
3
docs/todo.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
1. Make everything check the current thread's mta-ness
|
||||||
|
2. Write more documentation
|
||||||
|
3. Get someone to help write the Javadoc
|
||||||
4
jni/.cvsignore
Normal file
4
jni/.cvsignore
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
jacob.dll
|
||||||
|
jacob.lib
|
||||||
|
jacob.exp
|
||||||
|
|
||||||
@@ -410,9 +410,22 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev
|
|||||||
|
|
||||||
// check for error and display a somewhat verbose error message
|
// check for error and display a somewhat verbose error message
|
||||||
if (!SUCCEEDED(hr)) {
|
if (!SUCCEEDED(hr)) {
|
||||||
const char *nm = env->GetStringUTFChars(name, NULL);
|
// two buffers that may have to be freed later
|
||||||
char *buf = CreateErrorMsgFromInfo(hr, &excepInfo, nm);
|
char *buf = NULL;
|
||||||
env->ReleaseStringUTFChars(name, nm);
|
char *dispIdAsName = NULL;
|
||||||
|
// this method can get called with a name or a dispatch id
|
||||||
|
// we need to handle both SF 1114159
|
||||||
|
if (name != NULL){
|
||||||
|
const char *nm = env->GetStringUTFChars(name, NULL);
|
||||||
|
buf = CreateErrorMsgFromInfo(hr, &excepInfo, nm);
|
||||||
|
env->ReleaseStringUTFChars(name, nm);
|
||||||
|
} else {
|
||||||
|
dispIdAsName = new char[256];
|
||||||
|
// get the id string
|
||||||
|
itoa (dispID,dispIdAsName,10);
|
||||||
|
//continue on mostly as before
|
||||||
|
buf = CreateErrorMsgFromInfo(hr,&excepInfo,dispIdAsName);
|
||||||
|
}
|
||||||
|
|
||||||
// jacob-msg 3696 - SF 1053866
|
// jacob-msg 3696 - SF 1053866
|
||||||
if(hr == DISP_E_EXCEPTION)
|
if(hr == DISP_E_EXCEPTION)
|
||||||
@@ -429,6 +442,7 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev
|
|||||||
|
|
||||||
ThrowComFail(env, buf, hr);
|
ThrowComFail(env, buf, hr);
|
||||||
if (buf) delete buf;
|
if (buf) delete buf;
|
||||||
|
if (dispIdAsName) delete dispIdAsName;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,10 @@ void putProxy(JNIEnv *env, jobject arg, EventProxy *ep)
|
|||||||
* Signature: (LDispatch;Ljava/lang/Object;Ljava/lang/String;)V
|
* Signature: (LDispatch;Ljava/lang/Object;Ljava/lang/String;)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init2
|
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init2
|
||||||
(JNIEnv *env, jobject _this, jobject src, jobject sink, jstring _progid)
|
(JNIEnv *env,
|
||||||
|
jobject _this, jobject src,
|
||||||
|
jobject sink, jobject protoVariant,
|
||||||
|
jstring _progid)
|
||||||
{
|
{
|
||||||
USES_CONVERSION;
|
USES_CONVERSION;
|
||||||
// find progid if any
|
// find progid if any
|
||||||
@@ -104,10 +107,11 @@ JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init2
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HRESULT hr = pCPC->FindConnectionPoint(eventIID, &pCP);
|
HRESULT hr = pCPC->FindConnectionPoint(eventIID, &pCP);
|
||||||
DWORD dwEventCookie;
|
// VC++ 6.0 compiler realiized we weren't using this variable
|
||||||
|
//DWORD dwEventCookie;
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
EventProxy *ep = new EventProxy(env, sink, pCP, eventIID, mNames, mIDs, n_EventMethods);
|
EventProxy *ep = new EventProxy(env, sink, protoVariant, pCP, eventIID, mNames, mIDs, n_EventMethods);
|
||||||
// need to store ep on _this, in case it gets collected
|
// need to store ep on _this, in case it gets collected
|
||||||
putProxy(env, _this, ep);
|
putProxy(env, _this, ep);
|
||||||
} else {
|
} else {
|
||||||
@@ -121,9 +125,9 @@ JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init2
|
|||||||
* Signature: (LDispatch;Ljava/lang/Object;)V
|
* Signature: (LDispatch;Ljava/lang/Object;)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init
|
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init
|
||||||
(JNIEnv *env, jobject _this, jobject src, jobject sink)
|
(JNIEnv *env, jobject _this, jobject src, jobject sink, jobject protoVariant)
|
||||||
{
|
{
|
||||||
Java_com_jacob_com_DispatchEvents_init2(env,_this,src,sink,NULL);
|
Java_com_jacob_com_DispatchEvents_init2(env,_this,src,sink, protoVariant, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ extern "C" {
|
|||||||
* Signature: (LDispatch;Ljava/lang/Object;)V
|
* Signature: (LDispatch;Ljava/lang/Object;)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init
|
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init
|
||||||
(JNIEnv *, jobject, jobject, jobject);
|
(JNIEnv *, jobject, jobject, jobject, jobject);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: DispatchEvents
|
* Class: DispatchEvents
|
||||||
@@ -21,7 +21,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init
|
|||||||
* Signature: (LDispatch;Ljava/lang/Object;Ljava/lang/String;)V
|
* Signature: (LDispatch;Ljava/lang/Object;Ljava/lang/String;)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init2
|
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init2
|
||||||
(JNIEnv *, jobject, jobject, jobject, jstring);
|
(JNIEnv *, jobject, jobject, jobject, jobject, jstring);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: DispatchEvents
|
* Class: DispatchEvents
|
||||||
|
|||||||
@@ -28,34 +28,44 @@
|
|||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include "EventProxy.h"
|
#include "EventProxy.h"
|
||||||
|
#include "Variant.h"
|
||||||
|
|
||||||
// hook myself up as a listener for delegate
|
// hook myself up as a listener for delegate
|
||||||
EventProxy::EventProxy(JNIEnv *env, jobject aSinkObj,
|
EventProxy::EventProxy(JNIEnv *env,
|
||||||
|
jobject aSinkObj,
|
||||||
|
jobject aVariantObj,
|
||||||
CComPtr<IConnectionPoint> pConn,
|
CComPtr<IConnectionPoint> pConn,
|
||||||
IID eid, CComBSTR mName[], DISPID mID[], int mNum) :
|
IID eid,
|
||||||
|
CComBSTR mName[],
|
||||||
|
DISPID mID[],
|
||||||
|
int mNum) :
|
||||||
|
// initialize some variables
|
||||||
m_cRef(0), pCP(pConn),
|
m_cRef(0), pCP(pConn),
|
||||||
eventIID(eid), MethNum(mNum), MethName(mName),
|
eventIID(eid), MethNum(mNum), MethName(mName),
|
||||||
MethID(mID), JMethID(NULL), javaSinkClass(NULL),
|
MethID(mID), JMethID(NULL),
|
||||||
variantClassMethod(NULL)
|
javaSinkClass(NULL)
|
||||||
{
|
{
|
||||||
|
// don't really need the variant object but we keep a reference
|
||||||
|
// anyway
|
||||||
javaSinkObj = env->NewGlobalRef(aSinkObj);
|
javaSinkObj = env->NewGlobalRef(aSinkObj);
|
||||||
if (env->ExceptionOccurred()) { env->ExceptionDescribe();}
|
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();}
|
||||||
|
javaVariantObj = env->NewGlobalRef(aVariantObj);
|
||||||
|
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();}
|
||||||
|
|
||||||
// we need this to attach to the event invocation thread
|
// we need this to attach to the event invocation thread
|
||||||
env->GetJavaVM(&jvm);
|
env->GetJavaVM(&jvm);
|
||||||
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); }
|
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();}
|
||||||
AddRef();
|
AddRef();
|
||||||
HRESULT hr = pCP->Advise(this, &dwEventCookie);
|
HRESULT hr = pCP->Advise(this, &dwEventCookie);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
|
|
||||||
// create a mapping from the DISPID's to jmethodID's by using
|
// create a mapping from the DISPID's to jmethodID's by using
|
||||||
// the method names I extracted from the classinfo
|
// the method names I extracted from the classinfo
|
||||||
JMethID = new jmethodID[MethNum];
|
JMethID = new jmethodID[MethNum];
|
||||||
|
|
||||||
javaSinkClass = env->GetObjectClass(javaSinkObj);
|
javaSinkClass = env->GetObjectClass(javaSinkObj);
|
||||||
if (javaSinkClass == NULL){ printf("can't figure out java sink class"); }
|
if (javaSinkClass == NULL){ printf("can't figure out java sink class"); }
|
||||||
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); }
|
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();}
|
||||||
variantClassMethod = env->GetMethodID(javaSinkClass, "getVariantClass", "()Ljava/lang/Class;");
|
|
||||||
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); }
|
|
||||||
if (variantClassMethod == NULL) { printf("variantClassMethod == null\n"); }
|
|
||||||
|
|
||||||
const char *method;
|
const char *method;
|
||||||
for(int i=0;i<MethNum;i++)
|
for(int i=0;i<MethNum;i++)
|
||||||
@@ -69,6 +79,7 @@ EventProxy::EventProxy(JNIEnv *env, jobject aSinkObj,
|
|||||||
// if the user didn't implement all the methods
|
// if the user didn't implement all the methods
|
||||||
env->ExceptionClear();
|
env->ExceptionClear();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ThrowComFail(env, "Advise failed", hr);
|
ThrowComFail(env, "Advise failed", hr);
|
||||||
}
|
}
|
||||||
@@ -85,10 +96,10 @@ EventProxy::~EventProxy()
|
|||||||
#else
|
#else
|
||||||
jvm->AttachCurrentThread((void**)&env, NULL);
|
jvm->AttachCurrentThread((void**)&env, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
env->DeleteGlobalRef(javaSinkObj);
|
env->DeleteGlobalRef(javaSinkObj);
|
||||||
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); }
|
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();}
|
||||||
if (MethNum) {
|
if (MethNum) {
|
||||||
delete [] MethName;
|
delete [] MethName;
|
||||||
delete [] MethID;
|
delete [] MethID;
|
||||||
@@ -125,7 +136,8 @@ STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid,
|
|||||||
LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams,
|
LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams,
|
||||||
VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
|
VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
//Visual C++ 6.0 recognized this as an unused variable
|
||||||
|
//HRESULT hr;
|
||||||
jmethodID meth = 0;
|
jmethodID meth = 0;
|
||||||
JNIEnv *env = NULL;
|
JNIEnv *env = NULL;
|
||||||
|
|
||||||
@@ -146,29 +158,32 @@ STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid,
|
|||||||
{
|
{
|
||||||
// attach to the current running thread
|
// attach to the current running thread
|
||||||
#ifdef JNI_VERSION_1_2
|
#ifdef JNI_VERSION_1_2
|
||||||
jvm->AttachCurrentThread((void **)&env, jvm);
|
jvm->AttachCurrentThread((void **)&env, jvm);
|
||||||
#else
|
#else
|
||||||
jvm->AttachCurrentThread((void**)&env, NULL);
|
jvm->AttachCurrentThread((void**)&env, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// get variant class
|
// get variant class
|
||||||
jclass vClass;
|
jclass vClass = NULL;
|
||||||
// do this in a JACOB 1.8 backwards compatable way
|
// do this in a JACOB 1.8 backwards compatable way
|
||||||
// this succeeds if the class was loaded from the bootstrap class loader
|
// this succeeds if the class was loaded from the bootstrap class loader
|
||||||
vClass = env->FindClass("com/jacob/com/Variant");
|
//vClass = env->FindClass("com/jacob/com/Variant");
|
||||||
|
// this is guarenteed to work so there really isn't any need for the line above
|
||||||
|
// but I don't want to bust anything so we leave it in
|
||||||
|
// the following code exists to support launchers like JWS where jacob isn't
|
||||||
|
// in the system classloader so we wouldn't be able to create a variant class
|
||||||
if (vClass == NULL){
|
if (vClass == NULL){
|
||||||
// see if our call back class implements our "special" method
|
// there will be a stored up exception if FindClass failed so lets clear it
|
||||||
if (variantClassMethod != NULL){
|
if (env->ExceptionOccurred()) { env->ExceptionClear(); }
|
||||||
jobject variantFound = env->CallObjectMethod(javaSinkObj, variantClassMethod);
|
//printf("using variant class passed in via constructor\n");
|
||||||
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); }
|
jclass javaVariantClass = env->GetObjectClass(javaVariantObj);
|
||||||
if (variantFound == NULL) { printf("variantFound == null\n"); }
|
if (javaVariantClass == NULL){ printf("can't figure out java Variant class"); }
|
||||||
vClass = (jclass)variantFound;
|
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();}
|
||||||
} else {
|
vClass = javaVariantClass;
|
||||||
// dang they didn't. lets tell the user they are having a bad day
|
if (vClass == NULL){
|
||||||
printf("We're going to fail now in a way that is probably pretty ugly");
|
|
||||||
printf("This application is probably running from a launcher where system class loader knows not Jacob\n");
|
printf("This application is probably running from a launcher where system class loader knows not Jacob\n");
|
||||||
printf("The call back class does not implement 'Class getVariantClass()' that we can use to work around this\n");
|
printf("And for some reason we couldn't find the variant class from the passed in variant\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,16 +191,16 @@ STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid,
|
|||||||
int num = pDispParams->cArgs;
|
int num = pDispParams->cArgs;
|
||||||
// and the constructor
|
// and the constructor
|
||||||
jmethodID vCons = env->GetMethodID(vClass, "<init>", "()V");
|
jmethodID vCons = env->GetMethodID(vClass, "<init>", "()V");
|
||||||
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); }
|
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();}
|
||||||
// make an array of them
|
// make an array of them
|
||||||
jobjectArray varr = env->NewObjectArray(num, vClass, 0);
|
jobjectArray varr = env->NewObjectArray(num, vClass, 0);
|
||||||
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); }
|
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();}
|
||||||
int i,j;
|
int i,j;
|
||||||
for(i=num-1,j=0;i>=0;i--,j++)
|
for(i=num-1,j=0;i>=0;i--,j++)
|
||||||
{
|
{
|
||||||
// construct a java variant holder
|
// construct a java variant holder
|
||||||
jobject arg = env->NewObject(vClass, vCons);
|
jobject arg = env->NewObject(vClass, vCons);
|
||||||
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); }
|
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();}
|
||||||
// get the empty variant from it
|
// get the empty variant from it
|
||||||
VARIANT *va = extractVariant(env, arg);
|
VARIANT *va = extractVariant(env, arg);
|
||||||
// copy the value
|
// copy the value
|
||||||
@@ -193,11 +208,11 @@ STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid,
|
|||||||
// put it in the array
|
// put it in the array
|
||||||
env->SetObjectArrayElement(varr, j, arg);
|
env->SetObjectArrayElement(varr, j, arg);
|
||||||
env->DeleteLocalRef(arg);
|
env->DeleteLocalRef(arg);
|
||||||
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); }
|
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();}
|
||||||
}
|
}
|
||||||
// call the method
|
// call the method
|
||||||
env->CallVoidMethod(javaSinkObj, meth, varr);
|
env->CallVoidMethod(javaSinkObj, meth, varr);
|
||||||
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); }
|
if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();}
|
||||||
|
|
||||||
|
|
||||||
// Begin code from Jiffie team that copies parameters back from java to COM
|
// Begin code from Jiffie team that copies parameters back from java to COM
|
||||||
@@ -820,6 +835,7 @@ STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid,
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
zeroVariant(env, arg);
|
||||||
env->DeleteLocalRef(arg);
|
env->DeleteLocalRef(arg);
|
||||||
}
|
}
|
||||||
// End code from Jiffie team that copies parameters back from java to COM
|
// End code from Jiffie team that copies parameters back from java to COM
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ private:
|
|||||||
DWORD dwEventCookie; // connection point cookie
|
DWORD dwEventCookie; // connection point cookie
|
||||||
jobject javaSinkObj; // the java object to delegate calls
|
jobject javaSinkObj; // the java object to delegate calls
|
||||||
jclass javaSinkClass; // the java class of the object
|
jclass javaSinkClass; // the java class of the object
|
||||||
jmethodID variantClassMethod; // the method on the javaSinkObj that will return the Variant class
|
jobject javaVariantObj; // a variant object passed in so we can find Variant later
|
||||||
|
|
||||||
IID eventIID; // the interface iid passed in
|
IID eventIID; // the interface iid passed in
|
||||||
int MethNum;
|
int MethNum;
|
||||||
@@ -70,9 +70,14 @@ private:
|
|||||||
public:
|
public:
|
||||||
// constuct with a global JNI ref to a sink object
|
// constuct with a global JNI ref to a sink object
|
||||||
// to which we will delegate event callbacks
|
// to which we will delegate event callbacks
|
||||||
EventProxy(JNIEnv *jenv, jobject aSinkObj,
|
EventProxy(JNIEnv *jenv,
|
||||||
|
jobject aSinkObj,
|
||||||
|
jobject aVariantObj,
|
||||||
CComPtr<IConnectionPoint> pConn,
|
CComPtr<IConnectionPoint> pConn,
|
||||||
IID eventIID, CComBSTR *mName, DISPID *mID, int mNum);
|
IID eventIID,
|
||||||
|
CComBSTR *mName,
|
||||||
|
DISPID *mID,
|
||||||
|
int mNum);
|
||||||
~EventProxy();
|
~EventProxy();
|
||||||
|
|
||||||
// IUnknown methods
|
// IUnknown methods
|
||||||
|
|||||||
@@ -99,13 +99,12 @@ SAFEARRAY *copySA(SAFEARRAY *psa)
|
|||||||
VARIANT v1, v2;
|
VARIANT v1, v2;
|
||||||
|
|
||||||
VariantInit(&v1);
|
VariantInit(&v1);
|
||||||
VariantInit(&v2);
|
VariantInit(&v2);
|
||||||
V_VT(&v1) = VT_ARRAY | vt;
|
V_VT(&v1) = VT_ARRAY | vt;
|
||||||
V_ARRAY(&v1) = psa;
|
V_ARRAY(&v1) = psa;
|
||||||
VariantCopy(&v2, &v1);
|
VariantCopy(&v2, &v1);
|
||||||
SAFEARRAY *sa = V_ARRAY(&v2);
|
SAFEARRAY *sa = V_ARRAY(&v2);
|
||||||
VariantInit(&v2); // make sure it's not owned by this variant
|
VariantInit(&v2); // make sure it's not owned by this variant
|
||||||
|
|
||||||
VariantClear(&v2);
|
VariantClear(&v2);
|
||||||
VariantInit(&v1);
|
VariantInit(&v1);
|
||||||
VariantClear(&v1);
|
VariantClear(&v1);
|
||||||
@@ -1719,8 +1718,8 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setString__IILjava_lang_Stri
|
|||||||
ThrowComFail(env, "safearray object corrupted", -1);
|
ThrowComFail(env, "safearray object corrupted", -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (SafeArrayGetDim(sa) != 1) {
|
if (SafeArrayGetDim(sa) != 2) {
|
||||||
ThrowComFail(env, "safearray is not 1D", -1);
|
ThrowComFail(env, "safearray is not 2D", -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
VARTYPE vt;
|
VARTYPE vt;
|
||||||
@@ -2035,8 +2034,8 @@ JNIEXPORT jboolean JNICALL Java_com_jacob_com_SafeArray_getBoolean__II
|
|||||||
ThrowComFail(env, "safearray object corrupted", -1);
|
ThrowComFail(env, "safearray object corrupted", -1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (SafeArrayGetDim(sa) != 1) {
|
if (SafeArrayGetDim(sa) != 2) {
|
||||||
ThrowComFail(env, "safearray is not 1D", -1);
|
ThrowComFail(env, "safearray is not 2D", -1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
VARTYPE vt;
|
VARTYPE vt;
|
||||||
@@ -2110,10 +2109,10 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setBoolean__IIZ
|
|||||||
ThrowComFail(env, "safearray object corrupted", -1);
|
ThrowComFail(env, "safearray object corrupted", -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (SafeArrayGetDim(sa) != 1) {
|
if (SafeArrayGetDim(sa) != 2) {
|
||||||
ThrowComFail(env, "safearray is not 1D", -1);
|
ThrowComFail(env, "safearray is not 2D", -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
VARTYPE vt;
|
VARTYPE vt;
|
||||||
SafeArrayGetVartype(sa, &vt);
|
SafeArrayGetVartype(sa, &vt);
|
||||||
long idx[2] = {i,j};
|
long idx[2] = {i,j};
|
||||||
|
|||||||
@@ -91,6 +91,25 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_init
|
|||||||
env->SetIntField(_this, jf, (unsigned int)v);
|
env->SetIntField(_this, jf, (unsigned int)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_jacob_com_Variant
|
||||||
|
* Method: zeroVariant
|
||||||
|
* Signature: ()V
|
||||||
|
*
|
||||||
|
* This should only be used on variant objects created by teh
|
||||||
|
* com layer as part of a call through EventProxy.
|
||||||
|
* This zeros out the variant pointer in the Variant object
|
||||||
|
* so that the calling COM program can free the memory.
|
||||||
|
* instead of both the COM program and the Java GC doing it.
|
||||||
|
*/
|
||||||
|
void zeroVariant(JNIEnv *env, jobject _this)
|
||||||
|
{
|
||||||
|
jclass clazz = env->GetObjectClass(_this);
|
||||||
|
jfieldID jf = env->GetFieldID(clazz, VARIANT_FLD, "I");
|
||||||
|
env->SetIntField(_this, jf, (unsigned int)0);
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_Save
|
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_Save
|
||||||
(JNIEnv *env, jobject _this, jobject outStream)
|
(JNIEnv *env, jobject _this, jobject outStream)
|
||||||
{
|
{
|
||||||
@@ -351,6 +370,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDateRef
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SF 1065533 added unicode support
|
||||||
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putStringRef
|
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putStringRef
|
||||||
(JNIEnv *env, jobject _this, jstring s)
|
(JNIEnv *env, jobject _this, jstring s)
|
||||||
{
|
{
|
||||||
@@ -358,21 +378,15 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putStringRef
|
|||||||
if (v) {
|
if (v) {
|
||||||
VariantClear(v); // whatever was there before
|
VariantClear(v); // whatever was there before
|
||||||
|
|
||||||
// need to convert to C-style char buffer
|
const jchar *cStr = env->GetStringChars(s,NULL);
|
||||||
jclass strcls = env->FindClass("java/lang/String");
|
CComBSTR bs(cStr);
|
||||||
jmethodID getBytes = env->GetMethodID(strcls, "getBytes", "()[B");
|
|
||||||
jbyteArray ba = (jbyteArray)env->CallObjectMethod(s, getBytes);
|
|
||||||
int len = env->GetArrayLength(ba);
|
|
||||||
jbyte* buf = (jbyte*)alloca(len + 1);
|
|
||||||
env->GetByteArrayRegion(ba, 0, len, buf);
|
|
||||||
buf[len] = '\0';
|
|
||||||
CComBSTR bs((char*)buf);
|
|
||||||
|
|
||||||
BSTR *pbs = (BSTR *)CoTaskMemAlloc(sizeof(BSTR));
|
BSTR *pbs = (BSTR *)CoTaskMemAlloc(sizeof(BSTR));
|
||||||
bs.CopyTo(pbs);
|
bs.CopyTo(pbs);
|
||||||
V_VT(v) = VT_BSTR|VT_BYREF;
|
V_VT(v) = VT_BSTR|VT_BYREF;
|
||||||
V_BSTRREF(v) = pbs;
|
V_BSTRREF(v) = pbs;
|
||||||
}
|
|
||||||
|
env->ReleaseStringChars(s,cStr); }
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getShortRef
|
JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getShortRef
|
||||||
@@ -858,6 +872,7 @@ JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_getString
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SF 1065533 added unicode support
|
||||||
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putString
|
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putString
|
||||||
(JNIEnv *env, jobject _this, jstring s)
|
(JNIEnv *env, jobject _this, jstring s)
|
||||||
{
|
{
|
||||||
@@ -866,18 +881,13 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putString
|
|||||||
VariantClear(v); // whatever was there before
|
VariantClear(v); // whatever was there before
|
||||||
V_VT(v) = VT_BSTR;
|
V_VT(v) = VT_BSTR;
|
||||||
|
|
||||||
// get C-style byte array
|
const jchar *cStr = env->GetStringChars(s,NULL);
|
||||||
jclass strcls = env->FindClass("java/lang/String");
|
CComBSTR bs(cStr);
|
||||||
jmethodID getBytes = env->GetMethodID(strcls, "getBytes", "()[B");
|
|
||||||
jbyteArray ba = (jbyteArray)env->CallObjectMethod(s, getBytes);
|
|
||||||
int len = env->GetArrayLength(ba);
|
|
||||||
jbyte* buf = (jbyte*)alloca(len + 1);
|
|
||||||
env->GetByteArrayRegion(ba, 0, len, buf);
|
|
||||||
buf[len] = '\0';
|
|
||||||
|
|
||||||
CComBSTR bs((char*)buf);
|
|
||||||
V_VT(v) = VT_BSTR;
|
V_VT(v) = VT_BSTR;
|
||||||
V_BSTR(v) = bs.Copy();
|
V_BSTR(v) = bs.Copy();
|
||||||
|
|
||||||
|
env->ReleaseStringChars(s,cStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -607,6 +607,19 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_Load
|
|||||||
JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_isNull
|
JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_isNull
|
||||||
(JNIEnv *, jobject);
|
(JNIEnv *, jobject);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_jacob_com_Variant
|
||||||
|
* Method: zeroVariant
|
||||||
|
* Signature: ()V
|
||||||
|
*
|
||||||
|
* This should only be used on variant objects created by teh
|
||||||
|
* com layer as part of a call through EventProxy.
|
||||||
|
* This zeros out the variant pointer in the Variant object
|
||||||
|
* so that the calling COM program can free the memory.
|
||||||
|
* instead of both the COM program and the Java GC doing it.
|
||||||
|
*/
|
||||||
|
void zeroVariant (JNIEnv *, jobject);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
BIN
jni/jacob.dll
BIN
jni/jacob.dll
Binary file not shown.
BIN
jni/jacob.exp
BIN
jni/jacob.exp
Binary file not shown.
BIN
jni/jacob.lib
BIN
jni/jacob.lib
Binary file not shown.
51
jni/makefile
51
jni/makefile
@@ -1,51 +0,0 @@
|
|||||||
JDK = d:\j2sdk1.4.2_06
|
|
||||||
DEST_DIR = d:\jacob_18
|
|
||||||
MSDEVDIR = d:\apps\\"Microsoft Visual Studio"\VC98
|
|
||||||
|
|
||||||
JDK_INC = -I$(JDK)\include -I$(JDK)\include\win32
|
|
||||||
JDK_LIB = $(JDK)\lib\jvm.lib
|
|
||||||
MS_INC = -I$(MSDEVDIR)\Include -I$(MSDEVDIR)\ATL\Include
|
|
||||||
SYS_LIB = oleaut32.lib ole32.lib uuid.lib kernel32.lib shell32.lib user32.lib
|
|
||||||
OPT = /O2
|
|
||||||
CC = cl $(OPT) $(JDK_INC) $(MS_INC)
|
|
||||||
|
|
||||||
OBJFILES = stdafx.obj util.obj EventProxy.obj Variant.obj Dispatch.obj SafeArray.obj DispatchEvents.obj ComThread.obj EnumVariant.obj STA.obj DispatchProxy.obj
|
|
||||||
|
|
||||||
all: jacob.dll
|
|
||||||
cp jacob.dll $(DEST_DIR)
|
|
||||||
|
|
||||||
jacob.dll: $(OBJFILES)
|
|
||||||
link /dll /out:jacob.dll $(OBJFILES) $(JDK_LIB) $(SYS_LIB)
|
|
||||||
|
|
||||||
stdafx.obj: stdafx.cpp *.h
|
|
||||||
$(CC) -c stdafx.cpp
|
|
||||||
|
|
||||||
util.obj: util.cpp *.h
|
|
||||||
$(CC) -c util.cpp
|
|
||||||
|
|
||||||
EventProxy.obj: EventProxy.cpp *.h
|
|
||||||
$(CC) -c EventProxy.cpp
|
|
||||||
|
|
||||||
Variant.obj: Variant.cpp *.h
|
|
||||||
$(CC) -c Variant.cpp
|
|
||||||
|
|
||||||
Dispatch.obj: Dispatch.cpp *.h
|
|
||||||
$(CC) -c Dispatch.cpp
|
|
||||||
|
|
||||||
SafeArray.obj: SafeArray.cpp *.h
|
|
||||||
$(CC) -c SafeArray.cpp
|
|
||||||
|
|
||||||
DispatchEvents.obj: DispatchEvents.cpp *.h
|
|
||||||
$(CC) -c DispatchEvents.cpp
|
|
||||||
|
|
||||||
ComThread.obj: ComThread.cpp *.h
|
|
||||||
$(CC) -c ComThread.cpp
|
|
||||||
|
|
||||||
EnumVariant.obj: EnumVariant.cpp *.h
|
|
||||||
$(CC) -c EnumVariant.cpp
|
|
||||||
|
|
||||||
STA.obj: STA.cpp *.h
|
|
||||||
$(CC) -c STA.cpp
|
|
||||||
|
|
||||||
DispatchProxy.obj: DispatchProxy.cpp *.h
|
|
||||||
$(CC) -c DispatchProxy.cpp
|
|
||||||
@@ -5,6 +5,5 @@ extern "C" {
|
|||||||
IDispatch *extractDispatch(JNIEnv *env, jobject arg);
|
IDispatch *extractDispatch(JNIEnv *env, jobject arg);
|
||||||
SAFEARRAY *extractSA(JNIEnv *env, jobject arg);
|
SAFEARRAY *extractSA(JNIEnv *env, jobject arg);
|
||||||
void setSA(JNIEnv *env, jobject arg, SAFEARRAY *sa, int copy);
|
void setSA(JNIEnv *env, jobject arg, SAFEARRAY *sa, int copy);
|
||||||
|
SAFEARRAY *copySA(SAFEARRAY *psa);
|
||||||
SAFEARRAY *copySA(SAFEARRAY *psa)
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
makefile
18
makefile
@@ -1,18 +0,0 @@
|
|||||||
JAVAC = d:\j2sdk1.4.2_06\bin\javac -O
|
|
||||||
JAR = d:\j2sdk1.4.2_06\bin\jar -cvf jacob.jar
|
|
||||||
COM_DIR = com\jacob\com
|
|
||||||
ACX_DIR = com\jacob\activeX
|
|
||||||
|
|
||||||
all: java jni
|
|
||||||
rm -f jacobSrc_18.zip jacobBin_18.zip
|
|
||||||
jar -cvf jacobSrc_18.zip .
|
|
||||||
jar -cvf jacobBin_18.zip jacob.dll jacob.jar LICENSE.TXT README.TXT samples
|
|
||||||
|
|
||||||
java: jacob.jar
|
|
||||||
$(JAVAC) $(COM_DIR)\*.java $(ACX_DIR)\*.java
|
|
||||||
$(JAR) $(COM_DIR)\*.class $(ACX_DIR)\*.class
|
|
||||||
|
|
||||||
jni: jni\jacob.dll
|
|
||||||
cd jni
|
|
||||||
nmake -f makefile all
|
|
||||||
cd ..\
|
|
||||||
@@ -1,88 +1,88 @@
|
|||||||
- ADO Wrapper for JACOB - Copyright 1999, Dan Adler
|
- ADO Wrapper for JACOB - Copyright 1999, Dan Adler
|
||||||
|
|
||||||
This sample shows how to generate more strongly typed wrapper classes
|
This sample shows how to generate more strongly typed wrapper classes
|
||||||
for the JACOB automation classes. These are pure java classes which
|
for the JACOB automation classes. These are pure java classes which
|
||||||
extend com.jacob.com.Dispatch and delegate all the methods to the
|
extend com.jacob.com.Dispatch and delegate all the methods to the
|
||||||
unedrlying IDispatch pointer. This methodology is similar to the way
|
unedrlying IDispatch pointer. This methodology is similar to the way
|
||||||
MFC does automation wrappers, rather than using the @com directives
|
MFC does automation wrappers, rather than using the @com directives
|
||||||
to invisibly delegate the calls, as the Microsoft VM does.
|
to invisibly delegate the calls, as the Microsoft VM does.
|
||||||
|
|
||||||
The ADO wrappers in this directory are not a part of the JACOB
|
The ADO wrappers in this directory are not a part of the JACOB
|
||||||
distribution, however, they demonstrate the preferred way to create
|
distribution, however, they demonstrate the preferred way to create
|
||||||
wrappers around the core functionality. The wrappers included here are
|
wrappers around the core functionality. The wrappers included here are
|
||||||
not a complete set, but they could easily be extended to provide all
|
not a complete set, but they could easily be extended to provide all
|
||||||
the functionality of the com.ms.wfc.data classes.
|
the functionality of the com.ms.wfc.data classes.
|
||||||
|
|
||||||
The code in test.java demonstrates two ways to get a Recordset
|
The code in test.java demonstrates two ways to get a Recordset
|
||||||
from SQL Server. In this case, I query for the authors in the 'pubs'
|
from SQL Server. In this case, I query for the authors in the 'pubs'
|
||||||
database once by opening a Recordset object directly, and once by
|
database once by opening a Recordset object directly, and once by
|
||||||
using the Command and Connection objects. The same code, using the WFC
|
using the Command and Connection objects. The same code, using the WFC
|
||||||
wrappers can be found in ms\testms.java in case you want to compare
|
wrappers can be found in ms\testms.java in case you want to compare
|
||||||
the performace. You can run the test.java demo in the MS VM as well.
|
the performace. You can run the test.java demo in the MS VM as well.
|
||||||
|
|
||||||
The constructor of the wrapper is used to create an instance.
|
The constructor of the wrapper is used to create an instance.
|
||||||
For example, the user can write:
|
For example, the user can write:
|
||||||
|
|
||||||
Connection c = new Connection();
|
Connection c = new Connection();
|
||||||
|
|
||||||
The code for the Connection constructor is shown here:
|
The code for the Connection constructor is shown here:
|
||||||
|
|
||||||
public Connection()
|
public Connection()
|
||||||
{
|
{
|
||||||
super("ADODB.Connection");
|
super("ADODB.Connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
it simply delegates to the com.jacob.com.Dispatch constructor which
|
it simply delegates to the com.jacob.com.Dispatch constructor which
|
||||||
takes a ProgID.
|
takes a ProgID.
|
||||||
|
|
||||||
Since I don't have a tool like JACTIVEX yet to create the wrappers
|
Since I don't have a tool like JACTIVEX yet to create the wrappers
|
||||||
automatically from the type library, I created them by hand by using
|
automatically from the type library, I created them by hand by using
|
||||||
the JACTIVEX'ed version as a starting point, and replacing the @com
|
the JACTIVEX'ed version as a starting point, and replacing the @com
|
||||||
calls with delegated calls to JACOB classes. A simple PERL program
|
calls with delegated calls to JACOB classes. A simple PERL program
|
||||||
could probably be used to automate this step.
|
could probably be used to automate this step.
|
||||||
|
|
||||||
In order to return strongly typed wrappers from method calls, I had to
|
In order to return strongly typed wrappers from method calls, I had to
|
||||||
create a special constructor which constructs the wrapper class instance
|
create a special constructor which constructs the wrapper class instance
|
||||||
and copies over the IDispatch pointer. This is because I can't cast a
|
and copies over the IDispatch pointer. This is because I can't cast a
|
||||||
java Dispatch object to a super class object.
|
java Dispatch object to a super class object.
|
||||||
|
|
||||||
For example, the Command class has a method like this:
|
For example, the Command class has a method like this:
|
||||||
|
|
||||||
public Connection getActiveConnection();
|
public Connection getActiveConnection();
|
||||||
|
|
||||||
Ideally, I would like the wrapper code to say:
|
Ideally, I would like the wrapper code to say:
|
||||||
|
|
||||||
public Connection getActiveConnection()
|
public Connection getActiveConnection()
|
||||||
{
|
{
|
||||||
// this doesn't work
|
// this doesn't work
|
||||||
return (Connection)Dispatch.get(this, "ActiveConnection").toDispatch());
|
return (Connection)Dispatch.get(this, "ActiveConnection").toDispatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
Thereby wrapping the returned Dispatch pointer in a Connection object.
|
Thereby wrapping the returned Dispatch pointer in a Connection object.
|
||||||
But, since I can't cast in this way, I use the following construct:
|
But, since I can't cast in this way, I use the following construct:
|
||||||
|
|
||||||
public Connection getActiveConnection()
|
public Connection getActiveConnection()
|
||||||
{
|
{
|
||||||
// this works
|
// this works
|
||||||
return new Connection(Dispatch.get(this, "ActiveConnection").toDispatch());
|
return new Connection(Dispatch.get(this, "ActiveConnection").toDispatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
Which uses a special constructor inserted into the Connection class:
|
Which uses a special constructor inserted into the Connection class:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor is used instead of a case operation to
|
* This constructor is used instead of a case operation to
|
||||||
* turn a Dispatch object into a wider object - it must exist
|
* turn a Dispatch object into a wider object - it must exist
|
||||||
* in every wrapper class whose instances may be returned from
|
* in every wrapper class whose instances may be returned from
|
||||||
* method calls wrapped in VT_DISPATCH Variants.
|
* method calls wrapped in VT_DISPATCH Variants.
|
||||||
*/
|
*/
|
||||||
public Connection(Dispatch d)
|
public Connection(Dispatch d)
|
||||||
{
|
{
|
||||||
// take over the IDispatch pointer
|
// take over the IDispatch pointer
|
||||||
m_pDispatch = d.m_pDispatch;
|
m_pDispatch = d.m_pDispatch;
|
||||||
// null out the input's pointer
|
// null out the input's pointer
|
||||||
d.m_pDispatch = 0;
|
d.m_pDispatch = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
I have to add this constructor to any class whose instances I want
|
I have to add this constructor to any class whose instances I want
|
||||||
to return from wrapped calls.
|
to return from wrapped calls.
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.ado;
|
package com.jacob.samples.ado;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.ado;
|
package com.jacob.samples.ado;
|
||||||
|
|
||||||
// Enum: CommandTypeEnum
|
// Enum: CommandTypeEnum
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.ado;
|
package com.jacob.samples.ado;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.ado;
|
package com.jacob.samples.ado;
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
|
|
||||||
public class Field extends Dispatch
|
public class Field extends Dispatch
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.ado;
|
package com.jacob.samples.ado;
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
|
|
||||||
public class Fields extends Dispatch
|
public class Fields extends Dispatch
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.ado;
|
package com.jacob.samples.ado;
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
|
|
||||||
public class Recordset extends Dispatch
|
public class Recordset extends Dispatch
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.ado;
|
package com.jacob.samples.ado;
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
|
|
||||||
public class test
|
public class test
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<title>Applet Test (1.1)</title>
|
<title>Applet Test (1.1)</title>
|
||||||
<h1>Applet Test (1.1)</h1>
|
<h1>Applet Test (1.1)</h1>
|
||||||
<hr>
|
<hr>
|
||||||
<applet code=AppTest.class width=400 height=400>
|
<applet code=AppTest.class width=400 height=400>
|
||||||
</applet>
|
</applet>
|
||||||
<hr>
|
<hr>
|
||||||
<a href="AppTest.java">The source.</a>
|
<a href="AppTest.java">The source.</a>
|
||||||
<br>
|
<br>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.applet;
|
package com.jacob.samples.applet;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
@@ -16,7 +16,7 @@ public class AppTest extends Applet implements ActionListener
|
|||||||
TextField out;
|
TextField out;
|
||||||
Button calc;
|
Button calc;
|
||||||
ActiveXComponent sC = null;
|
ActiveXComponent sC = null;
|
||||||
Object sControl = null;
|
Dispatch sControl = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* startup method
|
* startup method
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.servlet;
|
package com.jacob.samples.servlet;
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.*;
|
||||||
import javax.servlet.http.*;
|
import javax.servlet.http.*;
|
||||||
@@ -44,7 +44,7 @@ public class JacobScript extends javax.servlet.http.HttpServlet
|
|||||||
String expr = (String)req.getParameter("expr");
|
String expr = (String)req.getParameter("expr");
|
||||||
// make sure we have a session
|
// make sure we have a session
|
||||||
HttpSession session = req.getSession(true);
|
HttpSession session = req.getSession(true);
|
||||||
Object sControl = null;
|
Dispatch sControl = null;
|
||||||
if (session.isNew())
|
if (session.isNew())
|
||||||
{
|
{
|
||||||
// initialize the control and store it on the session
|
// initialize the control and store it on the session
|
||||||
@@ -56,7 +56,7 @@ public class JacobScript extends javax.servlet.http.HttpServlet
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sControl = session.getValue("control");
|
sControl = (Dispatch)session.getValue("control");
|
||||||
}
|
}
|
||||||
Variant result = Dispatch.call(sControl, "Eval", expr);
|
Variant result = Dispatch.call(sControl, "Eval", expr);
|
||||||
// display a form
|
// display a form
|
||||||
@@ -1,44 +1,44 @@
|
|||||||
This sample runs in Weblogic 5.1 as a servlet.
|
This sample runs in Weblogic 5.1 as a servlet.
|
||||||
|
|
||||||
1. Compile this file (make sure you have jdk1.2 installed or the
|
1. Compile this file (make sure you have jdk1.2 installed or the
|
||||||
javax.servlet.* classes in your classpath).
|
javax.servlet.* classes in your classpath).
|
||||||
2. Make sure the weblogic policy file allows native access. The easiest
|
2. Make sure the weblogic policy file allows native access. The easiest
|
||||||
way is to replace the contents with this:
|
way is to replace the contents with this:
|
||||||
|
|
||||||
grant codeBase "file:d:/weblogic/-" {
|
grant codeBase "file:d:/weblogic/-" {
|
||||||
permission java.security.AllPermission;
|
permission java.security.AllPermission;
|
||||||
};
|
};
|
||||||
|
|
||||||
grant codeBase "file:/c:/classes/-" {
|
grant codeBase "file:/c:/classes/-" {
|
||||||
permission java.security.AllPermission;
|
permission java.security.AllPermission;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
grant codeBase "file:${java.home}/lib/ext/-" {
|
grant codeBase "file:${java.home}/lib/ext/-" {
|
||||||
permission java.security.AllPermission;
|
permission java.security.AllPermission;
|
||||||
};
|
};
|
||||||
|
|
||||||
grant {
|
grant {
|
||||||
permission java.security.AllPermission;
|
permission java.security.AllPermission;
|
||||||
};
|
};
|
||||||
|
|
||||||
3. Add the servlet to the weblogic.properties file:
|
3. Add the servlet to the weblogic.properties file:
|
||||||
|
|
||||||
weblogic.httpd.register.JacobScript=JacobScript
|
weblogic.httpd.register.JacobScript=JacobScript
|
||||||
|
|
||||||
4. Either add your CLASSPATH to weblogic.classpath in startWebLogic.cmd
|
4. Either add your CLASSPATH to weblogic.classpath in startWebLogic.cmd
|
||||||
or copy the com directory into weblogic/myserver/servletclasses
|
or copy the com directory into weblogic/myserver/servletclasses
|
||||||
|
|
||||||
5. Copy the jacob/samples/servlet/* into weblogic/myserver/servletclasses
|
5. Copy the jacob/samples/servlet/* into weblogic/myserver/servletclasses
|
||||||
6. Start weblogic
|
6. Start weblogic
|
||||||
|
|
||||||
7. Type the url: http://localhost:7001/JacobScript into the browser
|
7. Type the url: http://localhost:7001/JacobScript into the browser
|
||||||
(If you run on port 7001)
|
(If you run on port 7001)
|
||||||
|
|
||||||
8. Enter a VBScript expression like:
|
8. Enter a VBScript expression like:
|
||||||
1+2
|
1+2
|
||||||
Now
|
Now
|
||||||
"hello" & " world"
|
"hello" & " world"
|
||||||
etc.
|
etc.
|
||||||
and watch the MS Script control (which you must have installed)
|
and watch the MS Script control (which you must have installed)
|
||||||
evaluate and return the result.
|
evaluate and return the result.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
import com.jacob.activeX.*;
|
import com.jacob.activeX.*;
|
||||||
@@ -1,40 +1,40 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
import com.jacob.activeX.*;
|
import com.jacob.activeX.*;
|
||||||
|
|
||||||
class DispatchTest
|
class DispatchTest
|
||||||
{
|
{
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
{
|
{
|
||||||
ComThread.InitSTA();
|
ComThread.InitSTA();
|
||||||
|
|
||||||
ActiveXComponent xl = new ActiveXComponent("Excel.Application");
|
ActiveXComponent xl = new ActiveXComponent("Excel.Application");
|
||||||
Object xlo = xl.getObject();
|
Dispatch xlo = xl.getObject();
|
||||||
try {
|
try {
|
||||||
System.out.println("version="+xl.getProperty("Version"));
|
System.out.println("version="+xl.getProperty("Version"));
|
||||||
System.out.println("version="+Dispatch.get(xlo, "Version"));
|
System.out.println("version="+Dispatch.get(xlo, "Version"));
|
||||||
Dispatch.put(xlo, "Visible", new Variant(true));
|
Dispatch.put(xlo, "Visible", new Variant(true));
|
||||||
Object workbooks = xl.getProperty("Workbooks").toDispatch();
|
Dispatch workbooks = xl.getProperty("Workbooks").toDispatch();
|
||||||
Object workbook = Dispatch.get(workbooks,"Add").toDispatch();
|
Dispatch workbook = Dispatch.get(workbooks,"Add").toDispatch();
|
||||||
Object sheet = Dispatch.get(workbook,"ActiveSheet").toDispatch();
|
Dispatch sheet = Dispatch.get(workbook,"ActiveSheet").toDispatch();
|
||||||
Object a1 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
|
Dispatch a1 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
|
||||||
new Object[] {"A1"},
|
new Object[] {"A1"},
|
||||||
new int[1]).toDispatch();
|
new int[1]).toDispatch();
|
||||||
Object a2 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
|
Dispatch a2 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
|
||||||
new Object[] {"A2"},
|
new Object[] {"A2"},
|
||||||
new int[1]).toDispatch();
|
new int[1]).toDispatch();
|
||||||
Dispatch.put(a1, "Value", "123.456");
|
Dispatch.put(a1, "Value", "123.456");
|
||||||
Dispatch.put(a2, "Formula", "=A1*2");
|
Dispatch.put(a2, "Formula", "=A1*2");
|
||||||
System.out.println("a1 from excel:"+Dispatch.get(a1, "Value"));
|
System.out.println("a1 from excel:"+Dispatch.get(a1, "Value"));
|
||||||
System.out.println("a2 from excel:"+Dispatch.get(a2, "Value"));
|
System.out.println("a2 from excel:"+Dispatch.get(a2, "Value"));
|
||||||
Variant f = new Variant(false);
|
Variant f = new Variant(false);
|
||||||
Dispatch.call(workbook, "Close", f);
|
Dispatch.call(workbook, "Close", f);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
xl.invoke("Quit", new Variant[] {});
|
xl.invoke("Quit", new Variant[] {});
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
import com.jacob.activeX.*;
|
import com.jacob.activeX.*;
|
||||||
@@ -14,8 +14,9 @@ class IETest
|
|||||||
{
|
{
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
{
|
{
|
||||||
|
int delay = 5000; // msec
|
||||||
ActiveXComponent ie = new ActiveXComponent("clsid:0002DF01-0000-0000-C000-000000000046");
|
ActiveXComponent ie = new ActiveXComponent("clsid:0002DF01-0000-0000-C000-000000000046");
|
||||||
Object ieo = ie.getObject();
|
Dispatch ieo = ie.getObject();
|
||||||
try {
|
try {
|
||||||
Dispatch.put(ieo, "Visible", new Variant(true));
|
Dispatch.put(ieo, "Visible", new Variant(true));
|
||||||
Dispatch.put(ieo, "AddressBar", new Variant(true));
|
Dispatch.put(ieo, "AddressBar", new Variant(true));
|
||||||
@@ -28,9 +29,9 @@ class IETest
|
|||||||
optional.noParam();
|
optional.noParam();
|
||||||
|
|
||||||
Dispatch.call(ieo, "Navigate", new Variant("http://www.danadler.com/jacob"));
|
Dispatch.call(ieo, "Navigate", new Variant("http://www.danadler.com/jacob"));
|
||||||
try { Thread.sleep(5000); } catch (Exception e) {}
|
try { Thread.sleep(delay); } catch (Exception e) {}
|
||||||
Dispatch.call(ieo, "Navigate", new Variant("http://groups.yahoo.com/group/jacob-project"));
|
Dispatch.call(ieo, "Navigate", new Variant("http://groups.yahoo.com/group/jacob-project"));
|
||||||
try { Thread.sleep(5000); } catch (Exception e) {}
|
try { Thread.sleep(delay); } catch (Exception e) {}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JACOB Outlook sample contributed by
|
* JACOB Outlook sample contributed by
|
||||||
@@ -22,14 +22,14 @@ public class Outlook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void recurseFolders(int iIndent, Object o) {
|
private static void recurseFolders(int iIndent, Dispatch o) {
|
||||||
|
|
||||||
if (o == null) return;
|
if (o == null) return;
|
||||||
Object oFolders = Dispatch.get(o, "Folders").toDispatch();
|
Dispatch oFolders = Dispatch.get(o, "Folders").toDispatch();
|
||||||
// System.out.println("oFolders=" + oFolders);
|
// System.out.println("oFolders=" + oFolders);
|
||||||
if (oFolders == null) return;
|
if (oFolders == null) return;
|
||||||
|
|
||||||
Object oFolder = Dispatch.get(oFolders, "GetFirst").toDispatch();
|
Dispatch oFolder = Dispatch.get(oFolders, "GetFirst").toDispatch();
|
||||||
do {
|
do {
|
||||||
Object oFolderName = Dispatch.get(oFolder, "Name");
|
Object oFolderName = Dispatch.get(oFolder, "Name");
|
||||||
if (null == oFolderName) {
|
if (null == oFolderName) {
|
||||||
@@ -52,10 +52,10 @@ public class Outlook {
|
|||||||
try {
|
try {
|
||||||
System.out.println("version="+axOutlook.getProperty("Version"));
|
System.out.println("version="+axOutlook.getProperty("Version"));
|
||||||
|
|
||||||
Object oOutlook = axOutlook.getObject();
|
Dispatch oOutlook = axOutlook.getObject();
|
||||||
System.out.println("version="+Dispatch.get(oOutlook, "Version"));
|
System.out.println("version="+Dispatch.get(oOutlook, "Version"));
|
||||||
|
|
||||||
Object oNameSpace = axOutlook.getProperty("Session").toDispatch();
|
Dispatch oNameSpace = axOutlook.getProperty("Session").toDispatch();
|
||||||
System.out.println("oNameSpace=" + oNameSpace);
|
System.out.println("oNameSpace=" + oNameSpace);
|
||||||
|
|
||||||
recurseFolders(0, oNameSpace);
|
recurseFolders(0, oNameSpace);
|
||||||
@@ -1,57 +1,47 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
import com.jacob.activeX.*;
|
import com.jacob.activeX.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In this case the component is created and used in the same thread
|
* In this case the component is created and used in the same thread
|
||||||
* and it's an Apartment Threaded component, so we call InitSTA.
|
* and it's an Apartment Threaded component, so we call InitSTA.
|
||||||
*/
|
*/
|
||||||
class ScriptTest
|
class ScriptTest
|
||||||
{
|
{
|
||||||
public static void main(String args[]) throws Exception
|
public static void main(String args[]) throws Exception
|
||||||
{
|
{
|
||||||
ComThread.InitSTA(true);
|
ComThread.InitSTA(true);
|
||||||
DispatchEvents de = null;
|
DispatchEvents de = null;
|
||||||
Dispatch sControl = null;
|
Dispatch sControl = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String lang = "VBScript";
|
String lang = "VBScript";
|
||||||
ActiveXComponent sC = new ActiveXComponent("ScriptControl");
|
ActiveXComponent sC = new ActiveXComponent("ScriptControl");
|
||||||
sControl = (Dispatch)sC.getObject();
|
sControl = (Dispatch)sC.getObject();
|
||||||
Dispatch.put(sControl, "Language", lang);
|
Dispatch.put(sControl, "Language", lang);
|
||||||
errEvents te = new errEvents();
|
ScriptTestErrEvents te = new ScriptTestErrEvents();
|
||||||
de = new DispatchEvents(sControl, te);
|
de = new DispatchEvents(sControl, te);
|
||||||
Variant result = Dispatch.call(sControl, "Eval", args[0]);
|
Variant result = Dispatch.call(sControl, "Eval", args[0]);
|
||||||
// call it twice to see the objects reused
|
// call it twice to see the objects reused
|
||||||
result = Dispatch.call(sControl, "Eval", args[0]);
|
result = Dispatch.call(sControl, "Eval", args[0]);
|
||||||
// call it 3 times to see the objects reused
|
// call it 3 times to see the objects reused
|
||||||
result = Dispatch.call(sControl, "Eval", args[0]);
|
result = Dispatch.call(sControl, "Eval", args[0]);
|
||||||
System.out.println("eval("+args[0]+") = "+ result);
|
System.out.println("eval("+args[0]+") = "+ result);
|
||||||
} catch (ComException e) {
|
} catch (ComException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Integer I = null;
|
Integer I = null;
|
||||||
for(int i=1;i<1000000;i++)
|
for(int i=1;i<1000000;i++)
|
||||||
{
|
{
|
||||||
I = new Integer(i);
|
I = new Integer(i);
|
||||||
}
|
}
|
||||||
System.out.println(I);
|
System.out.println(I);
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
ComThread.quitMainSTA();
|
ComThread.quitMainSTA();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class errEvents {
|
|
||||||
public void Error(Variant[] args)
|
|
||||||
{
|
|
||||||
System.out.println("java callback for error!");
|
|
||||||
}
|
|
||||||
public void Timeout(Variant[] args)
|
|
||||||
{
|
|
||||||
System.out.println("java callback for error!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +1,98 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
import com.jacob.activeX.*;
|
import com.jacob.activeX.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This example demonstrates how to make calls between
|
* This example demonstrates how to make calls between
|
||||||
* two different STA's.
|
* two different STA's.
|
||||||
* First, to create an STA, you need to extend the STA class
|
* First, to create an STA, you need to extend the STA class
|
||||||
* and override its OnInit() method. This method will be called
|
* and override its OnInit() method. This method will be called
|
||||||
* in the STA's thread so you can use it to create your COM
|
* in the STA's thread so you can use it to create your COM
|
||||||
* components that will run in that STA.
|
* components that will run in that STA.
|
||||||
* If you then try to call methods on those components from other
|
* If you then try to call methods on those components from other
|
||||||
* threads (STA or MTA) - this will fail.
|
* threads (STA or MTA) - this will fail.
|
||||||
* You cannot create a component in an STA and call its methods
|
* You cannot create a component in an STA and call its methods
|
||||||
* from another thread.
|
* from another thread.
|
||||||
* You can use the DispatchProxy to get a proxy to any Dispatch
|
* You can use the DispatchProxy to get a proxy to any Dispatch
|
||||||
* that lives in another STA. This object has to be created in the
|
* that lives in another STA. This object has to be created in the
|
||||||
* STA that houses the Dispatch (in this case it's created in the
|
* STA that houses the Dispatch (in this case it's created in the
|
||||||
* OnInit method). Then, another thread can call the toDispatch()
|
* OnInit method). Then, another thread can call the toDispatch()
|
||||||
* method of DispatchProxy to get a local proxy. At most ONE (!)
|
* method of DispatchProxy to get a local proxy. At most ONE (!)
|
||||||
* thread can call toDispatch(), and the call can be made only once.
|
* thread can call toDispatch(), and the call can be made only once.
|
||||||
* This is because a IStream object is used to pass the proxy, and
|
* This is because a IStream object is used to pass the proxy, and
|
||||||
* it is only written once and closed when you read it.
|
* it is only written once and closed when you read it.
|
||||||
* If you need multiple threads to access a Dispatch pointer, then
|
* If you need multiple threads to access a Dispatch pointer, then
|
||||||
* create that many DispatchProxy objects.
|
* create that many DispatchProxy objects.
|
||||||
*/
|
*/
|
||||||
class ScriptTest2 extends STA
|
class ScriptTest2 extends STA
|
||||||
{
|
{
|
||||||
public static ActiveXComponent sC;
|
public static ActiveXComponent sC;
|
||||||
public static DispatchEvents de = null;
|
public static DispatchEvents de = null;
|
||||||
public static Dispatch sControl = null;
|
public static Dispatch sControl = null;
|
||||||
public static DispatchProxy sCon = null;
|
public static DispatchProxy sCon = null;
|
||||||
|
|
||||||
public boolean OnInit()
|
public boolean OnInit()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.out.println("OnInit");
|
System.out.println("OnInit");
|
||||||
System.out.println(Thread.currentThread());
|
System.out.println(Thread.currentThread());
|
||||||
String lang = "VBScript";
|
String lang = "VBScript";
|
||||||
sC = new ActiveXComponent("ScriptControl");
|
sC = new ActiveXComponent("ScriptControl");
|
||||||
sControl = (Dispatch)sC.getObject();
|
sControl = (Dispatch)sC.getObject();
|
||||||
|
|
||||||
// sCon can be called from another thread
|
// sCon can be called from another thread
|
||||||
sCon = new DispatchProxy(sControl);
|
sCon = new DispatchProxy(sControl);
|
||||||
|
|
||||||
Dispatch.put(sControl, "Language", lang);
|
Dispatch.put(sControl, "Language", lang);
|
||||||
errEvents te = new errEvents();
|
ScriptTestErrEvents te = new ScriptTestErrEvents();
|
||||||
de = new DispatchEvents(sControl, te);
|
de = new DispatchEvents(sControl, te);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnQuit()
|
public void OnQuit()
|
||||||
{
|
{
|
||||||
System.out.println("OnQuit");
|
System.out.println("OnQuit");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String args[]) throws Exception
|
public static void main(String args[]) throws Exception
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
ComThread.InitSTA();
|
ComThread.InitSTA();
|
||||||
ScriptTest2 script = new ScriptTest2();
|
ScriptTest2 script = new ScriptTest2();
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
|
|
||||||
// get a thread-local Dispatch from sCon
|
// get a thread-local Dispatch from sCon
|
||||||
Dispatch sc = sCon.toDispatch();
|
Dispatch sc = sCon.toDispatch();
|
||||||
|
|
||||||
// call a method on the thread-local Dispatch obtained
|
// call a method on the thread-local Dispatch obtained
|
||||||
// from the DispatchProxy. If you try to make the same
|
// from the DispatchProxy. If you try to make the same
|
||||||
// method call on the sControl object - you will get a
|
// method call on the sControl object - you will get a
|
||||||
// ComException.
|
// ComException.
|
||||||
Variant result = Dispatch.call(sc, "Eval", args[0]);
|
Variant result = Dispatch.call(sc, "Eval", args[0]);
|
||||||
System.out.println("eval("+args[0]+") = "+ result);
|
System.out.println("eval("+args[0]+") = "+ result);
|
||||||
script.quit();
|
script.quit();
|
||||||
System.out.println("called quit");
|
System.out.println("called quit");
|
||||||
} catch (ComException e) {
|
} catch (ComException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Integer I = null;
|
Integer I = null;
|
||||||
for(int i=1;i<1000000;i++)
|
for(int i=1;i<1000000;i++)
|
||||||
{
|
{
|
||||||
I = new Integer(i);
|
I = new Integer(i);
|
||||||
}
|
}
|
||||||
System.out.println(I);
|
System.out.println(I);
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
96
samples/com/jacob/samples/test/ScriptTest2ActiveX.java
Normal file
96
samples/com/jacob/samples/test/ScriptTest2ActiveX.java
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
|
import com.jacob.com.*;
|
||||||
|
import com.jacob.activeX.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This example demonstrates how to make calls between
|
||||||
|
* two different STA's.
|
||||||
|
* First, to create an STA, you need to extend the STA class
|
||||||
|
* and override its OnInit() method. This method will be called
|
||||||
|
* in the STA's thread so you can use it to create your COM
|
||||||
|
* components that will run in that STA.
|
||||||
|
* If you then try to call methods on those components from other
|
||||||
|
* threads (STA or MTA) - this will fail.
|
||||||
|
* You cannot create a component in an STA and call its methods
|
||||||
|
* from another thread.
|
||||||
|
* You can use the DispatchProxy to get a proxy to any Dispatch
|
||||||
|
* that lives in another STA. This object has to be created in the
|
||||||
|
* STA that houses the Dispatch (in this case it's created in the
|
||||||
|
* OnInit method). Then, another thread can call the toDispatch()
|
||||||
|
* method of DispatchProxy to get a local proxy. At most ONE (!)
|
||||||
|
* thread can call toDispatch(), and the call can be made only once.
|
||||||
|
* This is because a IStream object is used to pass the proxy, and
|
||||||
|
* it is only written once and closed when you read it.
|
||||||
|
* If you need multiple threads to access a Dispatch pointer, then
|
||||||
|
* create that many DispatchProxy objects.
|
||||||
|
*/
|
||||||
|
class ScriptTest2ActiveX extends STA
|
||||||
|
{
|
||||||
|
public static ActiveXComponent sC;
|
||||||
|
public static DispatchEvents de = null;
|
||||||
|
public static DispatchProxy sCon = null;
|
||||||
|
|
||||||
|
public boolean OnInit()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
System.out.println("OnInit");
|
||||||
|
System.out.println(Thread.currentThread());
|
||||||
|
String lang = "VBScript";
|
||||||
|
sC = new ActiveXComponent("ScriptControl");
|
||||||
|
|
||||||
|
// sCon can be called from another thread
|
||||||
|
sCon = new DispatchProxy(sC);
|
||||||
|
|
||||||
|
sC.setProperty("Language", lang);
|
||||||
|
ScriptTestErrEvents te = new ScriptTestErrEvents();
|
||||||
|
de = new DispatchEvents(sC, te);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnQuit()
|
||||||
|
{
|
||||||
|
System.out.println("OnQuit");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[]) throws Exception
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
ComThread.InitSTA();
|
||||||
|
ScriptTest2ActiveX script = new ScriptTest2ActiveX();
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
// get a thread-local Dispatch from sCon
|
||||||
|
ActiveXComponent sc = new ActiveXComponent(sCon.toDispatch());
|
||||||
|
|
||||||
|
// call a method on the thread-local Dispatch obtained
|
||||||
|
// from the DispatchProxy. If you try to make the same
|
||||||
|
// method call on the sControl object - you will get a
|
||||||
|
// ComException.
|
||||||
|
Variant result = sc.invoke("Eval", args[0]);
|
||||||
|
System.out.println("eval("+args[0]+") = "+ result);
|
||||||
|
script.quit();
|
||||||
|
System.out.println("called quit");
|
||||||
|
} catch (ComException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Integer I = null;
|
||||||
|
for(int i=1;i<1000000;i++)
|
||||||
|
{
|
||||||
|
I = new Integer(i);
|
||||||
|
}
|
||||||
|
System.out.println(I);
|
||||||
|
ComThread.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,68 +1,68 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
import com.jacob.activeX.*;
|
import com.jacob.activeX.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here we create the ScriptControl component in a separate MTA thread
|
* Here we create the ScriptControl component in a separate MTA thread
|
||||||
* and then call the Eval method from the main thread. The main thread
|
* and then call the Eval method from the main thread. The main thread
|
||||||
* must also be an MTA thread. If you try to create it as an STA
|
* must also be an MTA thread. If you try to create it as an STA
|
||||||
* then you will not be able to make calls into a component running
|
* then you will not be able to make calls into a component running
|
||||||
* in another thread.
|
* in another thread.
|
||||||
*/
|
*/
|
||||||
class ScriptTest3 extends Thread
|
class ScriptTest3 extends Thread
|
||||||
{
|
{
|
||||||
public static ActiveXComponent sC;
|
public static ActiveXComponent sC;
|
||||||
public static DispatchEvents de = null;
|
public static DispatchEvents de = null;
|
||||||
public static Dispatch sControl = null;
|
public static Dispatch sControl = null;
|
||||||
public static boolean quit = false;
|
public static boolean quit = false;
|
||||||
|
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ComThread.InitMTA();
|
ComThread.InitMTA();
|
||||||
System.out.println("OnInit");
|
System.out.println("OnInit");
|
||||||
String lang = "VBScript";
|
String lang = "VBScript";
|
||||||
sC = new ActiveXComponent("ScriptControl");
|
sC = new ActiveXComponent("ScriptControl");
|
||||||
sControl = (Dispatch)sC.getObject();
|
sControl = (Dispatch)sC.getObject();
|
||||||
Dispatch.put(sControl, "Language", lang);
|
Dispatch.put(sControl, "Language", lang);
|
||||||
errEvents te = new errEvents();
|
ScriptTestErrEvents te = new ScriptTestErrEvents();
|
||||||
de = new DispatchEvents(sControl, te);
|
de = new DispatchEvents(sControl, te);
|
||||||
System.out.println("sControl="+sControl);
|
System.out.println("sControl="+sControl);
|
||||||
while (!quit) sleep(100);
|
while (!quit) sleep(100);
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
System.out.println("worker thread exits");
|
System.out.println("worker thread exits");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String args[]) throws Exception
|
public static void main(String args[]) throws Exception
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
ComThread.InitMTA();
|
ComThread.InitMTA();
|
||||||
ScriptTest3 script = new ScriptTest3();
|
ScriptTest3 script = new ScriptTest3();
|
||||||
script.start();
|
script.start();
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
|
|
||||||
Variant result = Dispatch.call(sControl, "Eval", args[0]);
|
Variant result = Dispatch.call(sControl, "Eval", args[0]);
|
||||||
System.out.println("eval("+args[0]+") = "+ result);
|
System.out.println("eval("+args[0]+") = "+ result);
|
||||||
System.out.println("setting quit");
|
System.out.println("setting quit");
|
||||||
script.quit = true;
|
ScriptTest3.quit = true;
|
||||||
} catch (ComException e) {
|
} catch (ComException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
System.out.println("main done");
|
System.out.println("main done");
|
||||||
ComThread.Release();
|
ComThread.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
66
samples/com/jacob/samples/test/ScriptTest3ActiveX.java
Normal file
66
samples/com/jacob/samples/test/ScriptTest3ActiveX.java
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
|
import com.jacob.com.*;
|
||||||
|
import com.jacob.activeX.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Here we create the ScriptControl component in a separate MTA thread
|
||||||
|
* and then call the Eval method from the main thread. The main thread
|
||||||
|
* must also be an MTA thread. If you try to create it as an STA
|
||||||
|
* then you will not be able to make calls into a component running
|
||||||
|
* in another thread.
|
||||||
|
*/
|
||||||
|
class ScriptTest3ActiveX extends Thread
|
||||||
|
{
|
||||||
|
public static ActiveXComponent sC;
|
||||||
|
public static DispatchEvents de = null;
|
||||||
|
public static boolean quit = false;
|
||||||
|
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ComThread.InitMTA();
|
||||||
|
System.out.println("OnInit");
|
||||||
|
String lang = "VBScript";
|
||||||
|
sC = new ActiveXComponent("ScriptControl");
|
||||||
|
sC.setProperty("Language", lang);
|
||||||
|
ScriptTestErrEvents te = new ScriptTestErrEvents();
|
||||||
|
de = new DispatchEvents(sC, te);
|
||||||
|
System.out.println("sControl="+sC);
|
||||||
|
while (!quit) sleep(100);
|
||||||
|
ComThread.Release();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
System.out.println("worker thread exits");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[]) throws Exception
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
ComThread.InitMTA();
|
||||||
|
ScriptTest3ActiveX script = new ScriptTest3ActiveX();
|
||||||
|
script.start();
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
Variant result = sC.invoke("Eval", args[0]);
|
||||||
|
System.out.println("eval("+args[0]+") = "+ result);
|
||||||
|
System.out.println("setting quit");
|
||||||
|
ScriptTest3ActiveX.quit = true;
|
||||||
|
} catch (ComException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
System.out.println("main done");
|
||||||
|
ComThread.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
46
samples/com/jacob/samples/test/ScriptTestActiveX.java
Normal file
46
samples/com/jacob/samples/test/ScriptTestActiveX.java
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
|
import com.jacob.com.*;
|
||||||
|
import com.jacob.activeX.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In this case the component is created and used in the same thread
|
||||||
|
* and it's an Apartment Threaded component, so we call InitSTA.
|
||||||
|
*/
|
||||||
|
class ScriptTestActiveX
|
||||||
|
{
|
||||||
|
public static void main(String args[]) throws Exception
|
||||||
|
{
|
||||||
|
ComThread.InitSTA(true);
|
||||||
|
DispatchEvents de = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
String lang = "VBScript";
|
||||||
|
ActiveXComponent sC = new ActiveXComponent("ScriptControl");
|
||||||
|
sC.setProperty("Language",lang);
|
||||||
|
ScriptTestErrEvents te = new ScriptTestErrEvents();
|
||||||
|
de = new DispatchEvents(sC, te);
|
||||||
|
Variant result;
|
||||||
|
result = sC.invoke("Eval",args[0]);
|
||||||
|
// call it twice to see the objects reused
|
||||||
|
result = sC.invoke("Eval",args[0]);
|
||||||
|
// call it 3 times to see the objects reused
|
||||||
|
result = sC.invoke("Eval",args[0]);
|
||||||
|
System.out.println("eval("+args[0]+") = "+ result);
|
||||||
|
} catch (ComException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Integer I = null;
|
||||||
|
for(int i=1;i<1000000;i++)
|
||||||
|
{
|
||||||
|
I = new Integer(i);
|
||||||
|
}
|
||||||
|
System.out.println(I);
|
||||||
|
ComThread.Release();
|
||||||
|
ComThread.quitMainSTA();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
19
samples/com/jacob/samples/test/ScriptTestErrEvents.java
Normal file
19
samples/com/jacob/samples/test/ScriptTestErrEvents.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
|
import com.jacob.com.Variant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracted from ScriptTest so everyone can see this
|
||||||
|
*/
|
||||||
|
public class ScriptTestErrEvents {
|
||||||
|
|
||||||
|
public void Error(Variant[] args)
|
||||||
|
{
|
||||||
|
System.out.println("java callback for error!");
|
||||||
|
}
|
||||||
|
public void Timeout(Variant[] args)
|
||||||
|
{
|
||||||
|
System.out.println("java callback for error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,67 +1,67 @@
|
|||||||
// Face.cpp : Implementation of CMultiFaceApp and DLL registration.
|
// Face.cpp : Implementation of CMultiFaceApp and DLL registration.
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "MultiFace.h"
|
#include "MultiFace.h"
|
||||||
#include "Face.h"
|
#include "Face.h"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
|
||||||
STDMETHODIMP Face::InterfaceSupportsErrorInfo(REFIID riid)
|
STDMETHODIMP Face::InterfaceSupportsErrorInfo(REFIID riid)
|
||||||
{
|
{
|
||||||
static const IID* arr[] =
|
static const IID* arr[] =
|
||||||
{
|
{
|
||||||
&IID_IFace1,
|
&IID_IFace1,
|
||||||
&IID_IFace2,
|
&IID_IFace2,
|
||||||
&IID_IFace3,
|
&IID_IFace3,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
||||||
{
|
{
|
||||||
if (InlineIsEqualGUID(*arr[i],riid))
|
if (InlineIsEqualGUID(*arr[i],riid))
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP Face::get_Face1Name(BSTR *pVal)
|
STDMETHODIMP Face::get_Face1Name(BSTR *pVal)
|
||||||
{
|
{
|
||||||
// TODO: Add your implementation code here
|
// TODO: Add your implementation code here
|
||||||
*pVal = name1;
|
*pVal = name1;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP Face::put_Face1Name(BSTR newVal)
|
STDMETHODIMP Face::put_Face1Name(BSTR newVal)
|
||||||
{
|
{
|
||||||
// TODO: Add your implementation code here
|
// TODO: Add your implementation code here
|
||||||
name1 = newVal;
|
name1 = newVal;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP Face::get_Face2Nam(BSTR *pVal)
|
STDMETHODIMP Face::get_Face2Nam(BSTR *pVal)
|
||||||
{
|
{
|
||||||
// TODO: Add your implementation code here
|
// TODO: Add your implementation code here
|
||||||
*pVal = name2;
|
*pVal = name2;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP Face::put_Face2Nam(BSTR newVal)
|
STDMETHODIMP Face::put_Face2Nam(BSTR newVal)
|
||||||
{
|
{
|
||||||
// TODO: Add your implementation code here
|
// TODO: Add your implementation code here
|
||||||
name2 = newVal;
|
name2 = newVal;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP Face::get_Face3Name(BSTR *pVal)
|
STDMETHODIMP Face::get_Face3Name(BSTR *pVal)
|
||||||
{
|
{
|
||||||
// TODO: Add your implementation code here
|
// TODO: Add your implementation code here
|
||||||
*pVal = name3;
|
*pVal = name3;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP Face::put_Face3Name(BSTR newVal)
|
STDMETHODIMP Face::put_Face3Name(BSTR newVal)
|
||||||
{
|
{
|
||||||
// TODO: Add your implementation code here
|
// TODO: Add your implementation code here
|
||||||
name3 = newVal;
|
name3 = newVal;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -1,63 +1,63 @@
|
|||||||
// Face.h: Definition of the Face class
|
// Face.h: Definition of the Face class
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#if !defined(AFX_FACE_H__9BF24413_B2E0_11D4_A695_00104BFF3241__INCLUDED_)
|
#if !defined(AFX_FACE_H__9BF24413_B2E0_11D4_A695_00104BFF3241__INCLUDED_)
|
||||||
#define AFX_FACE_H__9BF24413_B2E0_11D4_A695_00104BFF3241__INCLUDED_
|
#define AFX_FACE_H__9BF24413_B2E0_11D4_A695_00104BFF3241__INCLUDED_
|
||||||
|
|
||||||
#if _MSC_VER > 1000
|
#if _MSC_VER > 1000
|
||||||
#pragma once
|
#pragma once
|
||||||
#endif // _MSC_VER > 1000
|
#endif // _MSC_VER > 1000
|
||||||
|
|
||||||
#include "resource.h" // main symbols
|
#include "resource.h" // main symbols
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Face
|
// Face
|
||||||
|
|
||||||
class Face :
|
class Face :
|
||||||
public IDispatchImpl<IFace1, &IID_IFace1, &LIBID_MULTIFACELib>,
|
public IDispatchImpl<IFace1, &IID_IFace1, &LIBID_MULTIFACELib>,
|
||||||
public IDispatchImpl<IFace2, &IID_IFace2, &LIBID_MULTIFACELib>,
|
public IDispatchImpl<IFace2, &IID_IFace2, &LIBID_MULTIFACELib>,
|
||||||
public IDispatchImpl<IFace3, &IID_IFace3, &LIBID_MULTIFACELib>,
|
public IDispatchImpl<IFace3, &IID_IFace3, &LIBID_MULTIFACELib>,
|
||||||
public ISupportErrorInfo,
|
public ISupportErrorInfo,
|
||||||
public CComObjectRoot,
|
public CComObjectRoot,
|
||||||
public CComCoClass<Face,&CLSID_Face>
|
public CComCoClass<Face,&CLSID_Face>
|
||||||
{
|
{
|
||||||
// IFace1
|
// IFace1
|
||||||
private:
|
private:
|
||||||
CComBSTR name1;
|
CComBSTR name1;
|
||||||
|
|
||||||
// IFace2
|
// IFace2
|
||||||
CComBSTR name2;
|
CComBSTR name2;
|
||||||
|
|
||||||
// IFace3
|
// IFace3
|
||||||
CComBSTR name3;
|
CComBSTR name3;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Face() {}
|
Face() {}
|
||||||
BEGIN_COM_MAP(Face)
|
BEGIN_COM_MAP(Face)
|
||||||
COM_INTERFACE_ENTRY2(IDispatch, IFace1)
|
COM_INTERFACE_ENTRY2(IDispatch, IFace1)
|
||||||
COM_INTERFACE_ENTRY(IFace1)
|
COM_INTERFACE_ENTRY(IFace1)
|
||||||
COM_INTERFACE_ENTRY(IFace2)
|
COM_INTERFACE_ENTRY(IFace2)
|
||||||
COM_INTERFACE_ENTRY(IFace3)
|
COM_INTERFACE_ENTRY(IFace3)
|
||||||
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||||||
END_COM_MAP()
|
END_COM_MAP()
|
||||||
//DECLARE_NOT_AGGREGATABLE(Face)
|
//DECLARE_NOT_AGGREGATABLE(Face)
|
||||||
// Remove the comment from the line above if you don't want your object to
|
// Remove the comment from the line above if you don't want your object to
|
||||||
// support aggregation.
|
// support aggregation.
|
||||||
|
|
||||||
DECLARE_REGISTRY_RESOURCEID(IDR_Face)
|
DECLARE_REGISTRY_RESOURCEID(IDR_Face)
|
||||||
// ISupportsErrorInfo
|
// ISupportsErrorInfo
|
||||||
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STDMETHOD(get_Face3Name)(/*[out, retval]*/ BSTR *pVal);
|
STDMETHOD(get_Face3Name)(/*[out, retval]*/ BSTR *pVal);
|
||||||
STDMETHOD(put_Face3Name)(/*[in]*/ BSTR newVal);
|
STDMETHOD(put_Face3Name)(/*[in]*/ BSTR newVal);
|
||||||
STDMETHOD(get_Face2Nam)(/*[out, retval]*/ BSTR *pVal);
|
STDMETHOD(get_Face2Nam)(/*[out, retval]*/ BSTR *pVal);
|
||||||
STDMETHOD(put_Face2Nam)(/*[in]*/ BSTR newVal);
|
STDMETHOD(put_Face2Nam)(/*[in]*/ BSTR newVal);
|
||||||
STDMETHOD(get_Face1Name)(/*[out, retval]*/ BSTR *pVal);
|
STDMETHOD(get_Face1Name)(/*[out, retval]*/ BSTR *pVal);
|
||||||
STDMETHOD(put_Face1Name)(/*[in]*/ BSTR newVal);
|
STDMETHOD(put_Face1Name)(/*[in]*/ BSTR newVal);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !defined(AFX_FACE_H__9BF24413_B2E0_11D4_A695_00104BFF3241__INCLUDED_)
|
#endif // !defined(AFX_FACE_H__9BF24413_B2E0_11D4_A695_00104BFF3241__INCLUDED_)
|
||||||
@@ -1,72 +1,72 @@
|
|||||||
// MultiFace.cpp : Implementation of DLL Exports.
|
// MultiFace.cpp : Implementation of DLL Exports.
|
||||||
|
|
||||||
|
|
||||||
// Note: Proxy/Stub Information
|
// Note: Proxy/Stub Information
|
||||||
// To build a separate proxy/stub DLL,
|
// To build a separate proxy/stub DLL,
|
||||||
// run nmake -f MultiFaceps.mk in the project directory.
|
// run nmake -f MultiFaceps.mk in the project directory.
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include <initguid.h>
|
#include <initguid.h>
|
||||||
#include "MultiFace.h"
|
#include "MultiFace.h"
|
||||||
|
|
||||||
#include "MultiFace_i.c"
|
#include "MultiFace_i.c"
|
||||||
#include "Face.h"
|
#include "Face.h"
|
||||||
|
|
||||||
|
|
||||||
CComModule _Module;
|
CComModule _Module;
|
||||||
|
|
||||||
BEGIN_OBJECT_MAP(ObjectMap)
|
BEGIN_OBJECT_MAP(ObjectMap)
|
||||||
OBJECT_ENTRY(CLSID_Face, Face)
|
OBJECT_ENTRY(CLSID_Face, Face)
|
||||||
END_OBJECT_MAP()
|
END_OBJECT_MAP()
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// DLL Entry Point
|
// DLL Entry Point
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||||
{
|
{
|
||||||
if (dwReason == DLL_PROCESS_ATTACH)
|
if (dwReason == DLL_PROCESS_ATTACH)
|
||||||
{
|
{
|
||||||
_Module.Init(ObjectMap, hInstance, &LIBID_MULTIFACELib);
|
_Module.Init(ObjectMap, hInstance, &LIBID_MULTIFACELib);
|
||||||
DisableThreadLibraryCalls(hInstance);
|
DisableThreadLibraryCalls(hInstance);
|
||||||
}
|
}
|
||||||
else if (dwReason == DLL_PROCESS_DETACH)
|
else if (dwReason == DLL_PROCESS_DETACH)
|
||||||
_Module.Term();
|
_Module.Term();
|
||||||
return TRUE; // ok
|
return TRUE; // ok
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Used to determine whether the DLL can be unloaded by OLE
|
// Used to determine whether the DLL can be unloaded by OLE
|
||||||
|
|
||||||
STDAPI DllCanUnloadNow(void)
|
STDAPI DllCanUnloadNow(void)
|
||||||
{
|
{
|
||||||
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
|
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Returns a class factory to create an object of the requested type
|
// Returns a class factory to create an object of the requested type
|
||||||
|
|
||||||
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
||||||
{
|
{
|
||||||
return _Module.GetClassObject(rclsid, riid, ppv);
|
return _Module.GetClassObject(rclsid, riid, ppv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// DllRegisterServer - Adds entries to the system registry
|
// DllRegisterServer - Adds entries to the system registry
|
||||||
|
|
||||||
STDAPI DllRegisterServer(void)
|
STDAPI DllRegisterServer(void)
|
||||||
{
|
{
|
||||||
// registers object, typelib and all interfaces in typelib
|
// registers object, typelib and all interfaces in typelib
|
||||||
return _Module.RegisterServer(TRUE);
|
return _Module.RegisterServer(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// DllUnregisterServer - Removes entries from the system registry
|
// DllUnregisterServer - Removes entries from the system registry
|
||||||
|
|
||||||
STDAPI DllUnregisterServer(void)
|
STDAPI DllUnregisterServer(void)
|
||||||
{
|
{
|
||||||
return _Module.UnregisterServer(TRUE);
|
return _Module.UnregisterServer(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,12 @@
|
|||||||
// stdafx.cpp : source file that includes just the standard includes
|
// stdafx.cpp : source file that includes just the standard includes
|
||||||
// stdafx.pch will be the pre-compiled header
|
// stdafx.pch will be the pre-compiled header
|
||||||
// stdafx.obj will contain the pre-compiled type information
|
// stdafx.obj will contain the pre-compiled type information
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#ifdef _ATL_STATIC_REGISTRY
|
#ifdef _ATL_STATIC_REGISTRY
|
||||||
#include <statreg.h>
|
#include <statreg.h>
|
||||||
#include <statreg.cpp>
|
#include <statreg.cpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <atlimpl.cpp>
|
#include <atlimpl.cpp>
|
||||||
@@ -1,27 +1,27 @@
|
|||||||
// stdafx.h : include file for standard system include files,
|
// stdafx.h : include file for standard system include files,
|
||||||
// or project specific include files that are used frequently,
|
// or project specific include files that are used frequently,
|
||||||
// but are changed infrequently
|
// but are changed infrequently
|
||||||
|
|
||||||
#if !defined(AFX_STDAFX_H__9BF24406_B2E0_11D4_A695_00104BFF3241__INCLUDED_)
|
#if !defined(AFX_STDAFX_H__9BF24406_B2E0_11D4_A695_00104BFF3241__INCLUDED_)
|
||||||
#define AFX_STDAFX_H__9BF24406_B2E0_11D4_A695_00104BFF3241__INCLUDED_
|
#define AFX_STDAFX_H__9BF24406_B2E0_11D4_A695_00104BFF3241__INCLUDED_
|
||||||
|
|
||||||
#if _MSC_VER > 1000
|
#if _MSC_VER > 1000
|
||||||
#pragma once
|
#pragma once
|
||||||
#endif // _MSC_VER > 1000
|
#endif // _MSC_VER > 1000
|
||||||
|
|
||||||
#define STRICT
|
#define STRICT
|
||||||
#ifndef _WIN32_WINNT
|
#ifndef _WIN32_WINNT
|
||||||
#define _WIN32_WINNT 0x0400
|
#define _WIN32_WINNT 0x0400
|
||||||
#endif
|
#endif
|
||||||
#define _ATL_APARTMENT_THREADED
|
#define _ATL_APARTMENT_THREADED
|
||||||
|
|
||||||
#include <atlbase.h>
|
#include <atlbase.h>
|
||||||
//You may derive a class from CComModule and use it if you want to override
|
//You may derive a class from CComModule and use it if you want to override
|
||||||
//something, but do not change the name of _Module
|
//something, but do not change the name of _Module
|
||||||
extern CComModule _Module;
|
extern CComModule _Module;
|
||||||
#include <atlcom.h>
|
#include <atlcom.h>
|
||||||
|
|
||||||
//{{AFX_INSERT_LOCATION}}
|
//{{AFX_INSERT_LOCATION}}
|
||||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||||
|
|
||||||
#endif // !defined(AFX_STDAFX_H__9BF24406_B2E0_11D4_A695_00104BFF3241__INCLUDED)
|
#endif // !defined(AFX_STDAFX_H__9BF24406_B2E0_11D4_A695_00104BFF3241__INCLUDED)
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
//{{NO_DEPENDENCIES}}
|
||||||
// Microsoft Developer Studio generated include file.
|
// Microsoft Developer Studio generated include file.
|
||||||
// Used by MultiFace.rc
|
// Used by MultiFace.rc
|
||||||
//
|
//
|
||||||
#define IDS_PROJNAME 100
|
#define IDS_PROJNAME 100
|
||||||
#define IDS_FACE_DESC 101
|
#define IDS_FACE_DESC 101
|
||||||
#define IDR_Face 102
|
#define IDR_Face 102
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 201
|
#define _APS_NEXT_RESOURCE_VALUE 201
|
||||||
#define _APS_NEXT_COMMAND_VALUE 32768
|
#define _APS_NEXT_COMMAND_VALUE 32768
|
||||||
#define _APS_NEXT_CONTROL_VALUE 201
|
#define _APS_NEXT_CONTROL_VALUE 201
|
||||||
#define _APS_NEXT_SYMED_VALUE 103
|
#define _APS_NEXT_SYMED_VALUE 103
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package samples.test.atl;
|
package com.jacob.samples.test.atl;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
import com.jacob.activeX.*;
|
import com.jacob.activeX.*;
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
This example demonstrates how to access multiple interfaces.
|
This example demonstrates how to access multiple interfaces.
|
||||||
|
|
||||||
To run it, chdir to MultiFace\Debug and run:
|
To run it, chdir to MultiFace\Debug and run:
|
||||||
regsvr32 MultiFace.dll
|
regsvr32 MultiFace.dll
|
||||||
|
|
||||||
Then, run (in this dir):
|
Then, run (in this dir):
|
||||||
java MultiFace
|
java MultiFace
|
||||||
|
|
||||||
As you can see from MultiFace\MultiFace.idl - there are 3 interfaces.
|
As you can see from MultiFace\MultiFace.idl - there are 3 interfaces.
|
||||||
|
|
||||||
By default JACOB attaches to the default interface.
|
By default JACOB attaches to the default interface.
|
||||||
|
|
||||||
The file MultiFace.java shows how to use the new Dispatch.QueryInterface
|
The file MultiFace.java shows how to use the new Dispatch.QueryInterface
|
||||||
to get access to the other interfaces.
|
to get access to the other interfaces.
|
||||||
@@ -1,38 +1,38 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This example uses the MathTest sample VB COM DLL under
|
* This example uses the MathTest sample VB COM DLL under
|
||||||
* the MathProj directory
|
* the MathProj directory
|
||||||
*/
|
*/
|
||||||
class math
|
class math
|
||||||
{
|
{
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
{
|
{
|
||||||
System.runFinalizersOnExit(true);
|
System.runFinalizersOnExit(true);
|
||||||
Dispatch test = new Dispatch("MathTest.Math");
|
Dispatch test = new Dispatch("MathTest.Math");
|
||||||
testEvents te = new testEvents();
|
testEvents te = new testEvents();
|
||||||
DispatchEvents de = new DispatchEvents(test, te);
|
DispatchEvents de = new DispatchEvents(test, te);
|
||||||
System.out.println(Dispatch.call(test, "Add", new Variant(1), new Variant(2)));
|
System.out.println(Dispatch.call(test, "Add", new Variant(1), new Variant(2)));
|
||||||
System.out.println(Dispatch.call(test, "Mult", new Variant(2), new Variant(2)));
|
System.out.println(Dispatch.call(test, "Mult", new Variant(2), new Variant(2)));
|
||||||
Variant v = Dispatch.call(test, "Mult", new Variant(2), new Variant(2));
|
Variant v = Dispatch.call(test, "Mult", new Variant(2), new Variant(2));
|
||||||
// this should return false
|
// this should return false
|
||||||
System.out.println("v.isNull="+v.isNull());
|
System.out.println("v.isNull="+v.isNull());
|
||||||
v = Dispatch.call(test, "getNothing");
|
v = Dispatch.call(test, "getNothing");
|
||||||
// these should return nothing
|
// these should return nothing
|
||||||
System.out.println("v.isNull="+v.isNull());
|
System.out.println("v.isNull="+v.isNull());
|
||||||
System.out.println("v.toDispatch="+v.toDispatch());
|
System.out.println("v.toDispatch="+v.toDispatch());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class testEvents {
|
class testEvents {
|
||||||
public void DoneAdd(Variant[] args)
|
public void DoneAdd(Variant[] args)
|
||||||
{
|
{
|
||||||
System.out.println("DoneAdd called in java");
|
System.out.println("DoneAdd called in java");
|
||||||
}
|
}
|
||||||
public void DoneMult(Variant[] args)
|
public void DoneMult(Variant[] args)
|
||||||
{
|
{
|
||||||
System.out.println("DoneMult called in java");
|
System.out.println("DoneMult called in java");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,41 +1,41 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
import com.jacob.activeX.*;
|
import com.jacob.activeX.*;
|
||||||
|
|
||||||
class sa_dispatch
|
class sa_dispatch
|
||||||
{
|
{
|
||||||
public static void main(String args[])
|
public static void main(String args[])
|
||||||
{
|
{
|
||||||
System.runFinalizersOnExit(true);
|
System.runFinalizersOnExit(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String lang = "VBScript";
|
String lang = "VBScript";
|
||||||
ActiveXComponent sC = new ActiveXComponent("ScriptControl");
|
ActiveXComponent sC = new ActiveXComponent("ScriptControl");
|
||||||
Dispatch sControl = (Dispatch)sC.getObject();
|
Dispatch sControl = (Dispatch)sC.getObject();
|
||||||
Dispatch.put(sControl, "Language", lang);
|
Dispatch.put(sControl, "Language", lang);
|
||||||
|
|
||||||
Variant result = Dispatch.call(sControl, "Eval", args[0]);
|
Variant result = Dispatch.call(sControl, "Eval", args[0]);
|
||||||
System.out.println("eval("+args[0]+") = "+ result);
|
System.out.println("eval("+args[0]+") = "+ result);
|
||||||
|
|
||||||
// wrap the script control in a variant
|
// wrap the script control in a variant
|
||||||
Variant v = new Variant(sControl);
|
Variant v = new Variant(sControl);
|
||||||
|
|
||||||
// create a safe array of type dispatch
|
// create a safe array of type dispatch
|
||||||
SafeArray sa = new SafeArray(Variant.VariantDispatch, 1);
|
SafeArray sa = new SafeArray(Variant.VariantDispatch, 1);
|
||||||
|
|
||||||
// put the variant in the array
|
// put the variant in the array
|
||||||
sa.setVariant(0, v);
|
sa.setVariant(0, v);
|
||||||
|
|
||||||
// take it back out
|
// take it back out
|
||||||
Variant v2 = sa.getVariant(0);
|
Variant v2 = sa.getVariant(0);
|
||||||
Dispatch d = v2.toDispatch();
|
Dispatch d = v2.toDispatch();
|
||||||
|
|
||||||
// make sure you can call eval on it
|
// make sure you can call eval on it
|
||||||
result = Dispatch.call(d, "Eval", args[0]);
|
result = Dispatch.call(d, "Eval", args[0]);
|
||||||
System.out.println("eval("+args[0]+") = "+ result);
|
System.out.println("eval("+args[0]+") = "+ result);
|
||||||
} catch (ComException e) {
|
} catch (ComException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,58 +1,58 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
|
|
||||||
class sa_test
|
class sa_test
|
||||||
{
|
{
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
{
|
{
|
||||||
System.runFinalizersOnExit(true);
|
System.runFinalizersOnExit(true);
|
||||||
SafeArray sa = new SafeArray(Variant.VariantVariant, 3);
|
SafeArray sa = new SafeArray(Variant.VariantVariant, 3);
|
||||||
|
|
||||||
sa.fromShortArray(new short[] {1,2,3});
|
sa.fromShortArray(new short[] {1,2,3});
|
||||||
System.out.println("sa short="+sa);
|
System.out.println("sa short="+sa);
|
||||||
int[] ai = sa.toIntArray();
|
int[] ai = sa.toIntArray();
|
||||||
for(int i=0;i<ai.length;i++) {
|
for(int i=0;i<ai.length;i++) {
|
||||||
System.out.println("toInt="+ai[i]);
|
System.out.println("toInt="+ai[i]);
|
||||||
}
|
}
|
||||||
double[] ad = sa.toDoubleArray();
|
double[] ad = sa.toDoubleArray();
|
||||||
for(int i=0;i<ad.length;i++) {
|
for(int i=0;i<ad.length;i++) {
|
||||||
System.out.println("toDouble="+ad[i]);
|
System.out.println("toDouble="+ad[i]);
|
||||||
}
|
}
|
||||||
sa.fromIntArray(new int[] {100000,200000,300000});
|
sa.fromIntArray(new int[] {100000,200000,300000});
|
||||||
System.out.println("sa int="+sa);
|
System.out.println("sa int="+sa);
|
||||||
ai = sa.toIntArray();
|
ai = sa.toIntArray();
|
||||||
for(int i=0;i<ai.length;i++) {
|
for(int i=0;i<ai.length;i++) {
|
||||||
System.out.println("toInt="+ai[i]);
|
System.out.println("toInt="+ai[i]);
|
||||||
}
|
}
|
||||||
ad = sa.toDoubleArray();
|
ad = sa.toDoubleArray();
|
||||||
for(int i=0;i<ad.length;i++) {
|
for(int i=0;i<ad.length;i++) {
|
||||||
System.out.println("toDouble="+ad[i]);
|
System.out.println("toDouble="+ad[i]);
|
||||||
}
|
}
|
||||||
Variant av[] = sa.toVariantArray();
|
Variant av[] = sa.toVariantArray();
|
||||||
for(int i=0;i<av.length;i++) {
|
for(int i=0;i<av.length;i++) {
|
||||||
System.out.println("toVariant="+av[i]);
|
System.out.println("toVariant="+av[i]);
|
||||||
}
|
}
|
||||||
sa.fromDoubleArray(new double[] {1.5,2.5,3.5});
|
sa.fromDoubleArray(new double[] {1.5,2.5,3.5});
|
||||||
System.out.println("sa double="+sa);
|
System.out.println("sa double="+sa);
|
||||||
sa.fromFloatArray(new float[] {1.5F,2.5F,3.5F});
|
sa.fromFloatArray(new float[] {1.5F,2.5F,3.5F});
|
||||||
System.out.println("sa float="+sa);
|
System.out.println("sa float="+sa);
|
||||||
sa.fromBooleanArray(new boolean[] {true, false, true, false});
|
sa.fromBooleanArray(new boolean[] {true, false, true, false});
|
||||||
System.out.println("sa bool="+sa);
|
System.out.println("sa bool="+sa);
|
||||||
av = sa.toVariantArray();
|
av = sa.toVariantArray();
|
||||||
for(int i=0;i<av.length;i++) {
|
for(int i=0;i<av.length;i++) {
|
||||||
System.out.println("toVariant="+av[i]);
|
System.out.println("toVariant="+av[i]);
|
||||||
}
|
}
|
||||||
sa.fromCharArray(new char[] {'a','b','c','d'});
|
sa.fromCharArray(new char[] {'a','b','c','d'});
|
||||||
System.out.println("sa char="+sa);
|
System.out.println("sa char="+sa);
|
||||||
sa.fromStringArray(new String[] {"hello", "from", "java", "com"});
|
sa.fromStringArray(new String[] {"hello", "from", "java", "com"});
|
||||||
System.out.println("sa string="+sa);
|
System.out.println("sa string="+sa);
|
||||||
av = sa.toVariantArray();
|
av = sa.toVariantArray();
|
||||||
for(int i=0;i<av.length;i++) {
|
for(int i=0;i<av.length;i++) {
|
||||||
System.out.println("toVariant="+av[i]);
|
System.out.println("toVariant="+av[i]);
|
||||||
}
|
}
|
||||||
sa.fromVariantArray(new Variant[] {
|
sa.fromVariantArray(new Variant[] {
|
||||||
new Variant(1), new Variant(2.3), new Variant("hi")});
|
new Variant(1), new Variant(2.3), new Variant("hi")});
|
||||||
System.out.println("sa variant="+sa);
|
System.out.println("sa variant="+sa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,61 +1,61 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
import com.jacob.activeX.*;
|
import com.jacob.activeX.*;
|
||||||
|
|
||||||
public class safearray
|
public class safearray
|
||||||
{
|
{
|
||||||
public static void main(java.lang.String[] args)
|
public static void main(java.lang.String[] args)
|
||||||
{
|
{
|
||||||
System.runFinalizersOnExit(true);
|
System.runFinalizersOnExit(true);
|
||||||
|
|
||||||
ActiveXComponent xl = new ActiveXComponent("Excel.Application");
|
ActiveXComponent xl = new ActiveXComponent("Excel.Application");
|
||||||
try {
|
try {
|
||||||
Object cell;
|
Dispatch cell;
|
||||||
Object cellstart;
|
Dispatch cellstart;
|
||||||
Object cellstop;
|
Dispatch cellstop;
|
||||||
SafeArray sAProdText;
|
SafeArray sAProdText;
|
||||||
Object workbooks = xl.getProperty("Workbooks").toDispatch();
|
Dispatch workbooks = xl.getProperty("Workbooks").toDispatch();
|
||||||
System.out.println("have workbooks");
|
System.out.println("have workbooks");
|
||||||
Object workbook = Dispatch.call(workbooks, "Open", "d:\\jacob_15\\samples\\test\\jacobtest.xls").toDispatch();
|
Dispatch workbook = Dispatch.call(workbooks, "Open", "d:\\jacob_15\\samples\\test\\jacobtest.xls").toDispatch();
|
||||||
System.out.println("Opened File - jacobtest.xls\n");
|
System.out.println("Opened File - jacobtest.xls\n");
|
||||||
Object sheet = Dispatch.get(workbook,"ActiveSheet").toDispatch();
|
Dispatch sheet = Dispatch.get(workbook,"ActiveSheet").toDispatch();
|
||||||
cell = Dispatch.invoke(sheet,"Range",Dispatch.Get,new Object[] {"A1:D1000"},new int[1]).toDispatch();
|
cell = Dispatch.invoke(sheet,"Range",Dispatch.Get,new Object[] {"A1:D1000"},new int[1]).toDispatch();
|
||||||
System.out.println("have cell:"+cell);
|
System.out.println("have cell:"+cell);
|
||||||
sAProdText = Dispatch.get(cell,"Value").toSafeArray();
|
sAProdText = Dispatch.get(cell,"Value").toSafeArray();
|
||||||
System.out.println("sa: dim="+sAProdText.getNumDim());
|
System.out.println("sa: dim="+sAProdText.getNumDim());
|
||||||
System.out.println("sa: start row="+sAProdText.getLBound(1));
|
System.out.println("sa: start row="+sAProdText.getLBound(1));
|
||||||
System.out.println("sa: start col="+sAProdText.getLBound(2));
|
System.out.println("sa: start col="+sAProdText.getLBound(2));
|
||||||
System.out.println("sa: end row="+sAProdText.getUBound(1));
|
System.out.println("sa: end row="+sAProdText.getUBound(1));
|
||||||
System.out.println("sa: end col="+sAProdText.getUBound(2));
|
System.out.println("sa: end col="+sAProdText.getUBound(2));
|
||||||
int i;
|
int i;
|
||||||
int lineNumber=1;
|
int lineNumber=1;
|
||||||
boolean stringFound = true;
|
boolean stringFound = true;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for(lineNumber=1; lineNumber < 1000; lineNumber++)
|
for(lineNumber=1; lineNumber < 1000; lineNumber++)
|
||||||
{
|
{
|
||||||
for (i = 1 ; i < 4 ; i++ ) {
|
for (i = 1 ; i < 4 ; i++ ) {
|
||||||
System.out.println((n++) + " " + lineNumber+" "+i+" " +sAProdText.getString(lineNumber,i));
|
System.out.println((n++) + " " + lineNumber+" "+i+" " +sAProdText.getString(lineNumber,i));
|
||||||
/*
|
/*
|
||||||
if (sAProdText.getString(lineNumber,i).compareTo("aaaa") != 0 ) {
|
if (sAProdText.getString(lineNumber,i).compareTo("aaaa") != 0 ) {
|
||||||
System.out.println("Invalid String in line " + lineNumber + " Cell " + i + " Value = " + sAProdText.getString(lineNumber,i));
|
System.out.println("Invalid String in line " + lineNumber + " Cell " + i + " Value = " + sAProdText.getString(lineNumber,i));
|
||||||
stringFound = false;
|
stringFound = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stringFound) {
|
if (stringFound) {
|
||||||
System.out.println("Valid Strings in line " + lineNumber);
|
System.out.println("Valid Strings in line " + lineNumber);
|
||||||
lineNumber++;
|
lineNumber++;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dispatch.call(workbook, "Close");
|
Dispatch.call(workbook, "Close");
|
||||||
System.out.println("Closed File\n");
|
System.out.println("Closed File\n");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
xl.invoke("Quit", new Variant[] {});
|
xl.invoke("Quit", new Variant[] {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
package samples.test;
|
package com.jacob.samples.test;
|
||||||
|
|
||||||
import com.jacob.com.*;
|
import com.jacob.com.*;
|
||||||
import com.jacob.activeX.*;
|
import com.jacob.activeX.*;
|
||||||
|
|
||||||
class speed
|
class speed
|
||||||
{
|
{
|
||||||
public static void main(String args[])
|
public static void main(String args[])
|
||||||
{
|
{
|
||||||
String lang = "VBScript";
|
String lang = "VBScript";
|
||||||
ActiveXComponent sC = new ActiveXComponent("ScriptControl");
|
ActiveXComponent sC = new ActiveXComponent("ScriptControl");
|
||||||
Object sControl = sC.getObject();
|
Dispatch sControl = sC.getObject();
|
||||||
Dispatch.put(sControl, "Language", lang);
|
Dispatch.put(sControl, "Language", lang);
|
||||||
for(int i=0;i<10000;i++) {
|
for(int i=0;i<10000;i++) {
|
||||||
Dispatch.call(sControl, "Eval", "1+1");
|
Dispatch.call(sControl, "Eval", "1+1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user