├── .gitignore ├── LICENSE.TXT ├── META-INF └── MANIFEST.MF ├── README.md ├── build.xml ├── docs ├── BuildingJacobFromSource.md ├── EventCallbacks.md ├── JacobComLifetime.md ├── JacobThreading.md ├── ReleaseNotes.md └── UsingJacob.md ├── lib ├── hamcrest-2.2.jar └── junit-4.13.jar ├── samples ├── README.md └── com │ └── jacob │ └── samples │ ├── JavaWebStart │ └── DLLFromJARClassLoader.java │ ├── MathProj │ ├── Math.cls │ ├── MathTest.dll │ ├── MathTest.exp │ ├── MathTest.java │ ├── MathTest.lib │ ├── MathTest.vbp │ ├── MathTest.vbw │ └── README.md │ ├── access │ ├── Access.java │ └── sample2.mdb │ ├── ado │ ├── ADO_README.md │ ├── Command.java │ ├── CommandTypeEnum.java │ ├── Connection.java │ ├── Field.java │ ├── Fields.java │ ├── Recordset.java │ ├── ms │ │ ├── README.md │ │ └── testms.java.txt │ └── test.java │ ├── applet │ ├── AppTest.html │ ├── Applet.html │ ├── Applet.jnlp │ ├── JacobTestApplet.java │ └── README.md │ ├── atl │ ├── MultiFace │ │ ├── Face.cpp │ │ ├── Face.h │ │ ├── Face.rgs │ │ ├── MultiFace.aps │ │ ├── MultiFace.cpp │ │ ├── MultiFace.def │ │ ├── MultiFace.dsp │ │ ├── MultiFace.dsw │ │ ├── MultiFace.h │ │ ├── MultiFace.idl │ │ ├── MultiFace.ncb │ │ ├── MultiFace.opt │ │ ├── MultiFace.plg │ │ ├── MultiFace.rc │ │ ├── MultiFace.tlb │ │ ├── MultiFace_i.c │ │ ├── MultiFace_p.c │ │ ├── MultiFaceps.def │ │ ├── MultiFaceps.mk │ │ ├── StdAfx.cpp │ │ ├── StdAfx.h │ │ ├── dlldata.c │ │ └── resource.h │ ├── MultiFaceTest.java │ └── README.md │ ├── office │ ├── ExcelDispatchTest.java │ ├── TestDocument.doc │ ├── VisioPrintTest.java │ ├── WordDocumentProperties.java │ └── ~$stDocument.doc │ ├── outlook │ └── Outlook.java │ ├── servlet │ ├── JacobScript.java_nocompile │ └── README.md │ ├── system │ ├── DiskUtils.java │ └── SystemMonitor.java │ └── visio │ ├── VisioApp.java │ ├── VisioAppFacade.java │ ├── VisioDemo.java │ ├── VisioEventAdapter.java │ ├── VisioEventListener.java │ ├── VisioException.java │ └── test_drawing.vsd ├── src ├── jni │ ├── .cvsignore │ ├── ComThread.cpp │ ├── ComThread.h │ ├── Dispatch.cpp │ ├── Dispatch.h │ ├── DispatchEvents.cpp │ ├── DispatchEvents.h │ ├── DispatchProxy.cpp │ ├── DispatchProxy.h │ ├── EnumVariant.cpp │ ├── EnumVariant.h │ ├── EventProxy.cpp │ ├── EventProxy.h │ ├── STA.cpp │ ├── STA.h │ ├── SafeArray.cpp │ ├── SafeArray.h │ ├── StdAfx.h │ ├── Variant.cpp │ ├── Variant.h │ ├── util.cpp │ └── util.h ├── main │ └── com │ │ └── jacob │ │ ├── activeX │ │ ├── ActiveXComponent.java │ │ ├── ActiveXDispatchEvents.java │ │ └── ActiveXInvocationProxy.java │ │ └── com │ │ ├── ComException.java │ │ ├── ComFailException.java │ │ ├── ComThread.java │ │ ├── Currency.java │ │ ├── DateUtilities.java │ │ ├── Dispatch.java │ │ ├── DispatchEvents.java │ │ ├── DispatchIdentifier.java │ │ ├── DispatchProxy.java │ │ ├── EnumVariant.java │ │ ├── InvocationProxy.java │ │ ├── InvocationProxyAllVariants.java │ │ ├── JacobException.java │ │ ├── JacobObject.java │ │ ├── JacobReleaseInfo.java │ │ ├── LibraryLoader.java │ │ ├── MainSTA.java │ │ ├── NotImplementedException.java │ │ ├── ROT.java │ │ ├── STA.java │ │ ├── SafeArray.java │ │ ├── Variant.java │ │ ├── VariantUtilities.java │ │ ├── VariantViaEvent.java │ │ └── WrongThreadException.java └── test │ ├── README.md │ └── com │ └── jacob │ ├── com │ ├── ActiveXComponentFactoryTest.java │ ├── CurrencyTest.java │ ├── DateUtilitiesTest.java │ ├── DispatchNullProgramIdTest.java │ ├── DispatchTest.java │ ├── DispatchValidDispatchTest.java │ ├── JacobDeadlockTest.java │ ├── JacobObjectTest.java │ ├── LibraryLoaderTest.java │ ├── README.md │ ├── ROT2Test.java │ ├── ROT3Test.java │ ├── ROTTest.java │ ├── VariantDateTest.java │ ├── VariantTest.java │ └── VariantUtilitiesTest.java │ └── test │ ├── BaseTestCase.java │ ├── errors │ └── UnicodeErrorTest.java │ ├── events │ ├── ExcelEventTest.java │ ├── IETest.java │ ├── IETestActiveXProxy.java │ └── WordEventTest.java │ ├── excel │ ├── ControllerTest.java │ └── teste.xls │ ├── powerpoint │ ├── PowerpointTest.java │ ├── test1.ppt │ ├── test2.ppt │ ├── test3.ppt │ ├── test4.ppt │ └── test5.ppt │ ├── safearray │ ├── SafeArrayBasicTest.java │ ├── SafeArrayContents.java │ ├── SafeArrayDispatchTest.java │ ├── SafeArrayLeakTest.java │ ├── SafeArrayReleaseTest.java │ ├── SafeArrayStringConstructorTest.java │ ├── SafeArrayViaExcel.xls │ └── SafeArrayViaExcelTest.java │ ├── vbscript │ ├── ScriptTest.java │ ├── ScriptTest2.java │ ├── ScriptTest2ActiveX.java │ ├── ScriptTest3.java │ ├── ScriptTest3ActiveX.java │ ├── ScriptTestActiveX.java │ └── ScriptTestErrEvents.java │ └── windowsmedia │ └── WMPlayer.java └── vstudio └── jacob └── jacob.vcproj /.gitignore: -------------------------------------------------------------------------------- 1 | jacob.dll 2 | jacob.jar 3 | jacobdll.jar 4 | *.zip 5 | RELEASE.txt 6 | .project 7 | .cproject 8 | .classpath 9 | compilation_tools.properties 10 | version.properties 11 | release 12 | .externalToolBuilders 13 | .cdtproject 14 | foo.foo 15 | foo.ser 16 | JacobVersion.properties 17 | .settings 18 | setenv.sh 19 | junit*properties 20 | ~$* 21 | settings.json 22 | 23 | /out 24 | /.idea 25 | *.iml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Java COM Bridge 2 | 3 | This document reflects the _next_ release _1.21_ which is moving from Java 8 to Java 17. 4 | 5 | Jacob is a Java library that lets Java applications communicate with Microsoft Windows DLLs or COM libraries. It does this through the use of a custom DLL that the Jacob Java classes communicate with via JNI. The Java library and dll isolate the Java developer from the underlying windows libraries so that the Java developer does not have to write custom JNI code.Jacob is not used for creating ActiveX plugins or other modules that live inside of Microsoft Windows applications. 6 | 7 | ## Repositories 8 | 9 | JACOB (Java-COM bridge) 10 | 11 | * Source was hosted on Sourceforge for for over a decade on the [jacob-project Sourceforge Repository](http://sourceforge.net/project/jacob-project) 12 | * The Discussion forums are still up on [Sourceforge jacob-project Discussions](https://sourceforge.net/p/jacob-project/discussion) 13 | * The root repository for source is now located [On GitHub](https://github.com/freemansoft/jacob-project) 14 | 15 | ## Documentation 16 | 17 | You can find additional information in the [docs](docs) folder 18 | 19 | * [Using Jacob](docs/UsingJacob.md) 20 | * [ReleaseNotes](docs/ReleaseNotes.md) 21 | * [Building Jacob From Source](docs/BuildingJacobFromSource.md) 22 | * Detailed instructions on creating a [build configuration file are in build.xml](build.xml) 23 | 24 | ## Usage 25 | 26 | * [Using Jacob](docs/UsingJacob.md) 27 | 28 | Put the appropriate DLL for your platform into your runtime library path. 29 | 30 | * jacob for 32 bit windows is located in /x86. 31 | * jacob for 64 bit windows is located in /64. 32 | 33 | ### TODO 34 | 35 | There is no good usage guide at this time. 36 | 37 | ## Release Notes 38 | 39 | See [ReleaseNotes](docs/ReleaseNotes.md) for a full history. 40 | 41 | ### Jacob 1.21 (latest) 42 | 43 | #### What's New in 1.21 44 | 45 | * Upgraded from VS 2019 to VS 2022 - can use Community 46 | * Formatting done using VS Code - developed using VSCode ANT and Java Extensions 47 | 48 | #### Tracked Changes 1.21 49 | 50 | | Item | Description | 51 | | -------------------------------------------------------- | ----------------------------------------------- | 52 | | **Bugs** | | 53 | | | Add Iterable to EnumVariant | 54 | | | Memory Leak | 55 | | | Implement Comparable on Currency | 56 | | | Incorrect delete in Dispatch JNI Invoke() | 57 | | | ArrayIndexOutOfBounds SafeArray | 58 | | | Memory Leaks in DispatchEvents.cpp | 59 | | | SaveArray init0 | 60 | | | Incorrect multi dimensional array element count | 61 | | | | 62 | | **Patches** | | 63 | | none | none | 64 | | | | 65 | | **Feature Requests** | | 66 | | none | none | 67 | -------------------------------------------------------------------------------- /docs/JacobComLifetime.md: -------------------------------------------------------------------------------- 1 | # COM Object Lifetime in JACOB 2 | 3 | ## introduction 4 | 5 | JACOB Version 1.7 implements a new [Threading Model](JacobThreading.html) that is more compatible with COM apartments. There is also an incompatibility between the Java object lifetime model and that of COM objects. COM Objects live and die by their reference count, whereas Java objects are collected by the Garbage Collector (GC) based on algortihms that are hidden from the user. 6 | 7 | ## COM Object Lifetime in JACOB Prior to Version 1.7 8 | 9 | In version 1.6 and earlier, JACOB objects which wrapped COM objects had `finalize()` methods that would call a native `release` method which would call a COM `Release`.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 issue is that finalizers are called from a separate thread, and, as was discussed in the [Threading Model](JacobThreading.html) 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 to run after we have terminated the thread that holds the component, in which case we would get fatal errors and crashes. 10 | 11 | ## COM Object Lifetime in JACOB in Version 1.7 12 | 13 | In Version 1.7, all JACOB objects which wrap COM objects extend `com.jacob.com.JacobObject`. This object has some special code to register itself with a `com.jacob.com.ROT` object which represents a Running Object Table (ROT). This table maps a Thread to the set of JacobObjects created in that thread. Therefore, when you call `ComThread.Release()`, the ROT checks whether that thread has created any objects, and these objects are released by calling their native `release` method (which is public).This lifetime management method ties the lifecycle to the thread's lifecycle rather than the GC. The JacobObject's still have finalizers, but they will typically not perform the native `release` since that has already been called. The native `release` methods were written such that you can call them multiple times without worrying - since they zero out the native pointer when called the first time.If you choose to call `release` methods on your objects yourself, that is allowed. In that case, when the thread is released the release calls will be no-ops.It becomes important for you to call `ComThread.Release()` on any thread before you allow it to exit, otherwise you may get some random crashes later on in your code. -------------------------------------------------------------------------------- /lib/hamcrest-2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/lib/hamcrest-2.2.jar -------------------------------------------------------------------------------- /lib/junit-4.13.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/lib/junit-4.13.jar -------------------------------------------------------------------------------- /samples/README.md: -------------------------------------------------------------------------------- 1 | # Samples directory 2 | 3 | Sample applications that are not run as part of the unit tests 4 | 5 | The ADO sample is a wrapper for the ADO classes. This demonstrates how 6 | to write JACOB wrappers. 7 | 8 | The applet sample shows how to use JACOB in an applet. The trick is to 9 | initialize and use the COM object in the same thread. 10 | 11 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/JavaWebStart/DLLFromJARClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.JavaWebStart; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.InputStream; 6 | 7 | import com.jacob.com.LibraryLoader; 8 | 9 | /** 10 | * It is sometimes necessary to run Jacob without being able to install the dll 11 | * on the client machine. This is true in JavaWebStart (JWS) and possibly Applet 12 | * (assuming security allows access to the file system). The obvious thing to do 13 | * here is to jar up the Jacob.dll so that it can be downloaded the client along 14 | * with the rest of the resources. This is simple except that the System.Load() 15 | * function does not search jar files for DLLs. It searches the classpath. The 16 | * work around to this problem is to write the DLL to a temporary file and then 17 | * explicitly load the DLL calling passing the full path to the temporary file. 18 | * 19 | * The following code demonstrates this idea. 20 | * 21 | * @author joe 22 | * 23 | */ 24 | public class DLLFromJARClassLoader { 25 | 26 | /** 27 | * Load the DLL from the classpath rather than from the java path. This code 28 | * uses this class's class loader to find the dell in one of the jar files 29 | * in this class's class path. It then writes the file as a temp file and 30 | * calls Load() on the temp file. The temporary file is marked to be deleted 31 | * on exit so the dll is deleted from the system when the application exits. 32 | *

33 | * Derived from ample code found in Sun's java forums 11 | * May need to run with some command line options (including from inside 12 | * Eclipse). Look in the docs area at the Jacob usage document for command line 13 | * options. 14 | */ 15 | class MathTest { 16 | /** 17 | * standard main program to run the sample 18 | * 19 | * @param args 20 | * command line parameters 21 | */ 22 | public static void main(String[] args) { 23 | MathTest me = new MathTest(); 24 | me.runTest(); 25 | } 26 | 27 | /** default constructor */ 28 | public MathTest() { 29 | } 30 | 31 | /** 32 | * not clear why we need a class and run method but that's the way it was 33 | * written 34 | */ 35 | public void runTest() { 36 | // deprecated 37 | // System.runFinalizersOnExit(true); 38 | Dispatch test = new ActiveXComponent("MathTest.Math"); 39 | TestEvents te = new TestEvents(); 40 | DispatchEvents de = new DispatchEvents(test, te); 41 | if (de == null) { 42 | System.out 43 | .println("null returned when trying to create DispatchEvents"); 44 | } 45 | System.out.println(Dispatch.call(test, "Add", new Variant(1), 46 | new Variant(2))); 47 | System.out.println(Dispatch.call(test, "Mult", new Variant(2), 48 | new Variant(2))); 49 | Variant v = Dispatch.call(test, "Mult", new Variant(2), new Variant(2)); 50 | // this should return false 51 | System.out.println("v.isNull=" + v.isNull()); 52 | v = Dispatch.call(test, "getNothing"); 53 | // these should return nothing 54 | System.out.println("v.isNull=" + v.isNull()); 55 | System.out.println("v.toDispatch=" + v.toDispatch()); 56 | } 57 | 58 | /** 59 | * 60 | * sample class to catch the events 61 | * 62 | */ 63 | public class TestEvents { 64 | /** 65 | * catches the DoneAdd event 66 | * 67 | * @param args 68 | */ 69 | public void DoneAdd(Variant[] args) { 70 | System.out.println("DoneAdd called in java"); 71 | } 72 | 73 | /** 74 | * catches the DoneMult event 75 | * 76 | * @param args 77 | */ 78 | public void DoneMult(Variant[] args) { 79 | System.out.println("DoneMult called in java"); 80 | } 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/MathProj/MathTest.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/samples/com/jacob/samples/MathProj/MathTest.lib -------------------------------------------------------------------------------- /samples/com/jacob/samples/MathProj/MathTest.vbp: -------------------------------------------------------------------------------- 1 | Type=OleDll 2 | Class=Math; Math.cls 3 | Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#C:\WINNT\System32\StdOle2.Tlb#OLE Automation 4 | Startup="(None)" 5 | HelpFile="" 6 | Title="MathTest" 7 | ExeName32="MathTest.dll" 8 | Command32="" 9 | Name="MathTest" 10 | HelpContextID="0" 11 | CompatibleMode="1" 12 | CompatibleEXE32="MathTest.dll" 13 | MajorVer=1 14 | MinorVer=0 15 | RevisionVer=0 16 | AutoIncrementVer=0 17 | ServerSupportFiles=0 18 | VersionCompanyName="Inventure America, Inc." 19 | CompilationType=0 20 | OptimizationType=0 21 | FavorPentiumPro(tm)=0 22 | CodeViewDebugInfo=0 23 | NoAliasing=0 24 | BoundsCheck=0 25 | OverflowCheck=0 26 | FlPointCheck=0 27 | FDIVCheck=0 28 | UnroundedFP=0 29 | StartMode=1 30 | Unattended=0 31 | Retained=0 32 | ThreadPerObject=0 33 | MaxNumberOfThreads=1 34 | ThreadingModel=1 35 | DebugStartupOption=0 36 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/MathProj/MathTest.vbw: -------------------------------------------------------------------------------- 1 | Math = 75, 13, 656, 554, 2 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/MathProj/README.md: -------------------------------------------------------------------------------- 1 | A Simple VB COM DLL that exposes two methods and raises events. 2 | 3 | The dll must be registered with your system 4 | ``` 5 | Run --> regsvr32 \com\jacob\test\MathProj\MathTest.dll 6 | ``` -------------------------------------------------------------------------------- /samples/com/jacob/samples/access/sample2.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/samples/com/jacob/samples/access/sample2.mdb -------------------------------------------------------------------------------- /samples/com/jacob/samples/ado/ADO_README.md: -------------------------------------------------------------------------------- 1 | - ADO Wrapper for JACOB - Copyright 1999, Dan Adler 2 | 3 | This sample shows how to generate more strongly typed wrapper classes 4 | for the JACOB automation classes. These are pure java classes which 5 | extend com.jacob.com.Dispatch and delegate all the methods to the 6 | unedrlying IDispatch pointer. This methodology is similar to the way 7 | MFC does automation wrappers, rather than using the @com directives 8 | to invisibly delegate the calls, as the Microsoft VM does. 9 | 10 | The ADO wrappers in this directory are not a part of the JACOB 11 | distribution, however, they demonstrate the preferred way to create 12 | wrappers around the core functionality. The wrappers included here are 13 | not a complete set, but they could easily be extended to provide all 14 | the functionality of the com.ms.wfc.data classes. 15 | 16 | The code in test.java demonstrates two ways to get a Recordset 17 | from SQL Server. In this case, I query for the authors in the 'pubs' 18 | database once by opening a Recordset object directly, and once by 19 | using the Command and Connection objects. The same code, using the WFC 20 | wrappers can be found in ms\testms.java in case you want to compare 21 | the performace. You can run the test.java demo in the MS VM as well. 22 | 23 | The constructor of the wrapper is used to create an instance. 24 | For example, the user can write: 25 | ```java 26 | Connection c = new Connection(); 27 | ``` 28 | The code for the Connection constructor is shown here: 29 | ```java 30 | public Connection() 31 | { 32 | super("ADODB.Connection"); 33 | } 34 | ``` 35 | it simply delegates to the com.jacob.com.Dispatch constructor which 36 | takes a ProgID. 37 | 38 | Since I don't have a tool like JACTIVEX yet to create the wrappers 39 | automatically from the type library, I created them by hand by using 40 | the JACTIVEX'ed version as a starting point, and replacing the @com 41 | calls with delegated calls to JACOB classes. A simple PERL program 42 | could probably be used to automate this step. 43 | 44 | In order to return strongly typed wrappers from method calls, I had to 45 | create a special constructor which constructs the wrapper class instance 46 | and copies over the IDispatch pointer. This is because I can't cast a 47 | java Dispatch object to a super class object. 48 | 49 | For example, the Command class has a method like this: 50 | ```java 51 | public Connection getActiveConnection(); 52 | ``` 53 | 54 | Ideally, I would like the wrapper code to say: 55 | ```java 56 | public Connection getActiveConnection() 57 | { 58 | // this doesn't work 59 | return (Connection)Dispatch.get(this, "ActiveConnection").toDispatch()); 60 | } 61 | ``` 62 | 63 | Thereby wrapping the returned Dispatch pointer in a Connection object. 64 | But, since I can't cast in this way, I use the following construct: 65 | ```java 66 | public Connection getActiveConnection() 67 | { 68 | // this works 69 | return new Connection(Dispatch.get(this, "ActiveConnection").toDispatch()); 70 | } 71 | ``` 72 | 73 | Which uses a special constructor inserted into the Connection class: 74 | 75 | ```java 76 | /** 77 | * This constructor is used instead of a case operation to 78 | * turn a Dispatch object into a wider object - it must exist 79 | * in every wrapper class whose instances may be returned from 80 | * method calls wrapped in VT_DISPATCH Variants. 81 | */ 82 | public Connection(Dispatch d) 83 | { 84 | // take over the IDispatch pointer 85 | m_pDispatch = d.m_pDispatch; 86 | // null out the input's pointer 87 | d.m_pDispatch = 0; 88 | } 89 | ``` 90 | 91 | I have to add this constructor to any class whose instances I want 92 | to return from wrapped calls. 93 | 94 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/ado/CommandTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.ado; 2 | 3 | // Enum: CommandTypeEnum 4 | 5 | public interface CommandTypeEnum { 6 | public static final int adCmdUnspecified = -1; 7 | public static final int adCmdUnknown = 8; 8 | public static final int adCmdText = 1; 9 | public static final int adCmdTable = 2; 10 | public static final int adCmdStoredProc = 4; 11 | public static final int adCmdFile = 256; 12 | public static final int adCmdTableDirect = 512; 13 | } 14 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/ado/Field.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.ado; 2 | 3 | import com.jacob.com.Dispatch; 4 | import com.jacob.com.Variant; 5 | 6 | public class Field extends Dispatch { 7 | /** 8 | * This constructor is used instead of a case operation to turn a Dispatch 9 | * object into a wider object - it must exist in every wrapper class whose 10 | * instances may be returned from method calls wrapped in VT_DISPATCH 11 | * Variants. 12 | */ 13 | public Field(Dispatch d) { 14 | super(d); 15 | } 16 | 17 | public Variant getProperties() { 18 | return Dispatch.get(this, "Properties"); 19 | } 20 | 21 | public int getActualSize() { 22 | return Dispatch.get(this, "ActualSize").getInt(); 23 | } 24 | 25 | public int getAttributes() { 26 | return Dispatch.get(this, "Attributes").getInt(); 27 | } 28 | 29 | public int getDefinedSize() { 30 | return Dispatch.get(this, "DefinedSize").getInt(); 31 | } 32 | 33 | public String getName() { 34 | return Dispatch.get(this, "Name").toString(); 35 | } 36 | 37 | public int getType() { 38 | return Dispatch.get(this, "Type").getInt(); 39 | } 40 | 41 | public Variant getValue() { 42 | return Dispatch.get(this, "Value"); 43 | } 44 | 45 | public void setValue(Variant pvar) { 46 | Dispatch.put(this, "Value", pvar); 47 | } 48 | 49 | public byte getPrecision() { 50 | return Dispatch.get(this, "Precision").getByte(); 51 | } 52 | 53 | public byte getNumericScale() { 54 | return Dispatch.get(this, "NumericScale").getByte(); 55 | } 56 | 57 | public void AppendChunk(Variant Data) { 58 | Dispatch.call(this, "AppendChunk", Data); 59 | } 60 | 61 | public Variant GetChunk(int Length) { 62 | return Dispatch.call(this, "GetChunk", new Variant(Length)); 63 | } 64 | 65 | public Variant getOriginalValue() { 66 | return Dispatch.get(this, "OriginalValue"); 67 | } 68 | 69 | public Variant getUnderlyingValue() { 70 | return Dispatch.get(this, "UnderlyingValue"); 71 | } 72 | 73 | public Variant getDataFormat() { 74 | return Dispatch.get(this, "DataFormat"); 75 | } 76 | 77 | public void setDataFormat(Variant ppiDF) { 78 | Dispatch.put(this, "DataFormat", ppiDF); 79 | } 80 | 81 | public void setPrecision(byte pb) { 82 | Dispatch.put(this, "Precision", new Variant(pb)); 83 | } 84 | 85 | public void setNumericScale(byte pb) { 86 | Dispatch.put(this, "NumericScale", new Variant(pb)); 87 | } 88 | 89 | public void setType(int pDataType) { 90 | Dispatch.put(this, "Type", new Variant(pDataType)); 91 | } 92 | 93 | public void setDefinedSize(int pl) { 94 | Dispatch.put(this, "DefinedSize", new Variant(pl)); 95 | } 96 | 97 | public void setAttributes(int pl) { 98 | Dispatch.put(this, "Attributes", new Variant(pl)); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/ado/Fields.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.ado; 2 | 3 | import com.jacob.com.Dispatch; 4 | import com.jacob.com.Variant; 5 | 6 | public class Fields extends Dispatch { 7 | /** 8 | * This constructor is used instead of a case operation to turn a Dispatch 9 | * object into a wider object - it must exist in every wrapper class whose 10 | * instances may be returned from method calls wrapped in VT_DISPATCH 11 | * Variants. 12 | */ 13 | public Fields(Dispatch d) { 14 | super(d); 15 | } 16 | 17 | public int getCount() { 18 | return Dispatch.get(this, "Count").getInt(); 19 | } 20 | 21 | public Variant _NewEnum() { 22 | return Dispatch.call(this, "_NewEnum"); 23 | } 24 | 25 | public void Refresh() { 26 | Dispatch.call(this, "Refresh"); 27 | } 28 | 29 | public Field getItem(int Index) { 30 | return new Field(Dispatch.call(this, "Item", new Variant(Index)) 31 | .toDispatch()); 32 | } 33 | 34 | public void Append(String Name, int Type, int DefinedSize, int Attrib) { 35 | Dispatch.call(this, "Append", Name, new Variant(Type), new Variant( 36 | DefinedSize), new Variant(Attrib)); 37 | } 38 | 39 | public void Delete(Variant Index) { 40 | Dispatch.call(this, "Delete", Index); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/ado/ms/README.md: -------------------------------------------------------------------------------- 1 | This is the WFC equivalent of the JACOB ADO example. 2 | 3 | This code must be compiled with JVC and run with JVIEW. 4 | 5 | The file testms.java has been renamed to tesetms.java.txt 6 | because most folks building this application will 7 | not have the MS JVM installed and will get compiler 8 | warnings. The MS JVM is going away eventually 9 | so this whole test will eventually go away. -------------------------------------------------------------------------------- /samples/com/jacob/samples/ado/ms/testms.java.txt: -------------------------------------------------------------------------------- 1 | package samples.ado.ms; 2 | 3 | import com.ms.com.*; 4 | import com.ms.wfc.data.*; 5 | 6 | // an ms-only version of test.java 7 | public class testms 8 | { 9 | public static void printRS(Recordset rs) 10 | { 11 | Fields fs = rs.getFields(); 12 | 13 | for (int i=0;i Recordset"); 47 | Connection c = new Connection(); 48 | c.setConnectionString(con); 49 | c.open(); 50 | Command comm = new Command(); 51 | comm.setActiveConnection(c); 52 | comm.setCommandType(AdoEnums.CommandType.TEXT); 53 | comm.setCommandText(query); 54 | Recordset rs = comm.execute(); 55 | printRS(rs); 56 | c.close(); 57 | } 58 | 59 | public static void main(String[] args) 60 | { 61 | String connectStr = "DRIVER=SQL Server;SERVER=DANADLER;UID=sa;PWD=;WSID=DANADLER;DATABASE=pubs"; 62 | String queryStr = "select * from authors"; 63 | getCommand(connectStr, queryStr); 64 | getRS(connectStr, queryStr); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/ado/test.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.ado; 2 | 3 | import com.jacob.com.Variant; 4 | 5 | public class test { 6 | public static void printRS(Recordset rs) { 7 | Fields fs = rs.getFields(); 8 | 9 | for (int i = 0; i < fs.getCount(); i++) { 10 | System.out.print(fs.getItem(i).getName() + " "); 11 | } 12 | System.out.println(""); 13 | 14 | rs.MoveFirst(); 15 | while (!rs.getEOF()) { 16 | for (int i = 0; i < fs.getCount(); i++) { 17 | Field f = fs.getItem(i); 18 | Variant v = f.getValue(); 19 | System.out.print(v + " "); 20 | } 21 | System.out.println(""); 22 | rs.MoveNext(); 23 | } 24 | } 25 | 26 | // open a recordset directly 27 | public static void getRS(String con, String query) { 28 | System.out.println("Recordset Open"); 29 | Recordset rs = new Recordset(); 30 | rs.Open(new Variant(query), new Variant(con)); 31 | printRS(rs); 32 | } 33 | 34 | // create connection and command objects and use them 35 | // to get a recordset 36 | public static void getCommand(String con, String query) { 37 | System.out.println("Command+Connection -> Recordset"); 38 | Connection c = new Connection(); 39 | c.setConnectionString(con); 40 | c.Open(); 41 | Command comm = new Command(); 42 | comm.setActiveConnection(c); 43 | comm.setCommandType(CommandTypeEnum.adCmdText); 44 | comm.setCommandText(query); 45 | Recordset rs = comm.Execute(); 46 | printRS(rs); 47 | c.Close(); 48 | } 49 | 50 | public static void main(String[] args) { 51 | String connectStr = "DRIVER=SQL Server;SERVER=DANADLER;UID=sa;PWD=;WSID=DANADLER;DATABASE=pubs"; 52 | String queryStr = "select * from authors"; 53 | getCommand(connectStr, queryStr); 54 | getRS(connectStr, queryStr); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/applet/AppTest.html: -------------------------------------------------------------------------------- 1 | Applet Test (1.1) 2 |

Applet Test (1.1)

3 |
4 | 5 | 6 |
7 | The source. 8 |
9 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/applet/Applet.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Jacob Test Applet 4 | 5 | 6 | 11 | 12 | Java is not working! Several reasons:
13 | 1.) Your Browser is not able to execute java (-> get a different browser e.g. firefox.com)
14 | 2.) Java is not installed (-> install java e.g. java.com)
15 | 3.) Java is disabled/deactivated (-> enable java in your web browser)
16 | 4.) Your security settings are too tight (->enable java the settings)
17 | 5.) Contact support @ nepatec
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/applet/Applet.jnlp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Jacob Test Applet 6 | ttreeck, nepatec GmbH & Co. KG 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/applet/JacobTestApplet.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.applet; 2 | 3 | import java.applet.Applet; 4 | import java.awt.Button; 5 | import java.awt.FlowLayout; 6 | import java.awt.TextField; 7 | import java.awt.event.ActionEvent; 8 | import java.awt.event.ActionListener; 9 | 10 | import com.jacob.activeX.ActiveXComponent; 11 | import com.jacob.com.Dispatch; 12 | import com.jacob.com.Variant; 13 | 14 | /** 15 | * Example applet to demonstrate: 16 | * 1. The use of jacob from an applet 17 | * 2. To show how to distribute the jacob native lib with the applet (also works with webstart) 18 | * 19 | * Comment on 2.: 20 | * The way shown here is quite straight forward and it is not necessary to use 21 | * a mechanism like the "DLLFromJARClassLoader" or something similar... 22 | * 23 | * @author ttreeck, www.nepatec.de 24 | * 25 | */ 26 | 27 | public class JacobTestApplet extends Applet implements ActionListener { 28 | 29 | private static final long serialVersionUID = 4492492907986849158L; 30 | 31 | TextField in; 32 | TextField out; 33 | Button calc; 34 | ActiveXComponent sC = null; 35 | 36 | /** 37 | * startup method 38 | */ 39 | @Override 40 | public void init() { 41 | setLayout(new FlowLayout()); 42 | add(this.in = new TextField("1+1", 16)); 43 | add(this.out = new TextField("?", 16)); 44 | add(this.calc = new Button("Calculate")); 45 | this.calc.addActionListener(this); 46 | 47 | } 48 | 49 | /** 50 | * Returns information about this applet. 51 | * According to the java spec: 52 | * "An applet should override this method to return a String containing information about the author, version, and copyright of the applet." 53 | * 54 | * @return information about the applet. 55 | */ 56 | @Override 57 | public String getAppletInfo() { 58 | return "Jacob Test Applet. Written by ttreeck, nepatec GmbH & Co. KG.\nhttp://www.nepatec.de"; 59 | } 60 | 61 | /** 62 | * Returns information about the parameters that are understood by this applet. 63 | * According to the java spec: 64 | * "An applet should override this method to return an array of Strings describing these parameters." 65 | * 66 | * @return array with a set of three Strings containing the name, the type, and a description. 67 | */ 68 | 69 | @Override 70 | public String[][] getParameterInfo(){ 71 | return new String[][]{}; 72 | } 73 | 74 | /** 75 | * action method that receives button actions 76 | * 77 | * @param ev the event 78 | */ 79 | public void actionPerformed(ActionEvent ev) { 80 | if (this.sC == null) { 81 | String lang = "VBScript"; 82 | this.sC = new ActiveXComponent("ScriptControl"); 83 | Dispatch.put(this.sC, "Language", lang); 84 | } 85 | Variant v = Dispatch.call(this.sC, "Eval", this.in.getText()); 86 | this.out.setText(v.toString()); 87 | } 88 | } -------------------------------------------------------------------------------- /samples/com/jacob/samples/applet/README.md: -------------------------------------------------------------------------------- 1 | There is an easy and elegant way to load DLLs from Applets and JavaWebStart Applications. 2 | 3 | Both JavaWebStart and Applets support JNLP (Applets since 1.6.0_10 aka plugin2). 4 | Within a jnlp file it is possible to specify a nativelib and that's it! 5 | So what do you need to do? 6 | 7 | 1. package the jacob-1.XX-xXX.dll into a jar file (root level of the jar, not into a subfolder) and put it into your applications lib folder next to your other libs (e.g. jacob.jar) 8 | 2. Specify all your libraries in your jnlp file like this: 9 | 10 | ```xml 11 | 12 | 13 | 14 | 15 | My cool Application or Applet 16 | nepatec GmbH & Co. KG 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | 41 | some crazy arguments 42 | 43 | 44 | ``` 45 | 46 | 3. Sign all the jars or set up a policy file (cp. Applet Security below) 47 | 4. Deploy your application and start it via webstart or as an applet (from an webpage) 48 | 49 | 50 | ## General comments ## 51 | 52 | * If you sign the jar files you need the tag - when using a policy file it can be removed 53 | * furthermore it is recommended that all libs are signed with an official certificate (e.g. from verisign, thawte etc) so that the browser doesn't pop a warning stating 'untrusted' application... 54 | * to check the validity of your jnlp file the tool JaNeLA (link cp. sources below) is recommended. 55 | 56 | ## Sources ## 57 | * [New Applet](https://jdk6.dev.java.net/plugin2/) 58 | * [Applet JNLP](https://jdk6.dev.java.net/plugin2/jnlp/) 59 | * [Applet Security](http://java.sun.com/developer/onlineTraining/Programming/JDCBook/appA.html) 60 | * [JNLP API](http://www.oracle.com/technetwork/java/javase/index-141367.html) 61 | * [JNLP Verifier](http://pscode.org/janela/) -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/Face.cpp: -------------------------------------------------------------------------------- 1 | // Face.cpp : Implementation of CMultiFaceApp and DLL registration. 2 | 3 | #include "stdafx.h" 4 | #include "MultiFace.h" 5 | #include "Face.h" 6 | 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | 10 | STDMETHODIMP Face::InterfaceSupportsErrorInfo(REFIID riid) 11 | { 12 | static const IID* arr[] = 13 | { 14 | &IID_IFace1, 15 | &IID_IFace2, 16 | &IID_IFace3, 17 | }; 18 | 19 | for (int i=0;i 1000 9 | #pragma once 10 | #endif // _MSC_VER > 1000 11 | 12 | #include "resource.h" // main symbols 13 | 14 | ///////////////////////////////////////////////////////////////////////////// 15 | // Face 16 | 17 | class Face : 18 | public IDispatchImpl, 19 | public IDispatchImpl, 20 | public IDispatchImpl, 21 | public ISupportErrorInfo, 22 | public CComObjectRoot, 23 | public CComCoClass 24 | { 25 | // IFace1 26 | private: 27 | CComBSTR name1; 28 | 29 | // IFace2 30 | CComBSTR name2; 31 | 32 | // IFace3 33 | CComBSTR name3; 34 | 35 | public: 36 | Face() {} 37 | BEGIN_COM_MAP(Face) 38 | COM_INTERFACE_ENTRY2(IDispatch, IFace1) 39 | COM_INTERFACE_ENTRY(IFace1) 40 | COM_INTERFACE_ENTRY(IFace2) 41 | COM_INTERFACE_ENTRY(IFace3) 42 | COM_INTERFACE_ENTRY(ISupportErrorInfo) 43 | END_COM_MAP() 44 | //DECLARE_NOT_AGGREGATABLE(Face) 45 | // Remove the comment from the line above if you don't want your object to 46 | // support aggregation. 47 | 48 | DECLARE_REGISTRY_RESOURCEID(IDR_Face) 49 | // ISupportsErrorInfo 50 | STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid); 51 | 52 | 53 | 54 | public: 55 | STDMETHOD(get_Face3Name)(/*[out, retval]*/ BSTR *pVal); 56 | STDMETHOD(put_Face3Name)(/*[in]*/ BSTR newVal); 57 | STDMETHOD(get_Face2Nam)(/*[out, retval]*/ BSTR *pVal); 58 | STDMETHOD(put_Face2Nam)(/*[in]*/ BSTR newVal); 59 | STDMETHOD(get_Face1Name)(/*[out, retval]*/ BSTR *pVal); 60 | STDMETHOD(put_Face1Name)(/*[in]*/ BSTR newVal); 61 | }; 62 | 63 | #endif // !defined(AFX_FACE_H__9BF24413_B2E0_11D4_A695_00104BFF3241__INCLUDED_) 64 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/Face.rgs: -------------------------------------------------------------------------------- 1 | HKCR 2 | { 3 | MultiFace.Face.1 = s 'Face Class' 4 | { 5 | CLSID = s '{9BF24412-B2E0-11D4-A695-00104BFF3241}' 6 | } 7 | MultiFace.Face = s 'Face Class' 8 | { 9 | CLSID = s '{9BF24412-B2E0-11D4-A695-00104BFF3241}' 10 | } 11 | NoRemove CLSID 12 | { 13 | ForceRemove {9BF24412-B2E0-11D4-A695-00104BFF3241} = s 'Face Class' 14 | { 15 | ProgID = s 'MultiFace.Face.1' 16 | VersionIndependentProgID = s 'MultiFace.Face' 17 | InprocServer32 = s '%MODULE%' 18 | { 19 | val ThreadingModel = s 'both' 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFace.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/samples/com/jacob/samples/atl/MultiFace/MultiFace.aps -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFace.cpp: -------------------------------------------------------------------------------- 1 | // MultiFace.cpp : Implementation of DLL Exports. 2 | 3 | 4 | // Note: Proxy/Stub Information 5 | // To build a separate proxy/stub DLL, 6 | // run nmake -f MultiFaceps.mk in the project directory. 7 | 8 | #include "stdafx.h" 9 | #include "resource.h" 10 | #include 11 | #include "MultiFace.h" 12 | 13 | #include "MultiFace_i.c" 14 | #include "Face.h" 15 | 16 | 17 | CComModule _Module; 18 | 19 | BEGIN_OBJECT_MAP(ObjectMap) 20 | OBJECT_ENTRY(CLSID_Face, Face) 21 | END_OBJECT_MAP() 22 | 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // DLL Entry Point 25 | 26 | extern "C" 27 | BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) 28 | { 29 | if (dwReason == DLL_PROCESS_ATTACH) 30 | { 31 | _Module.Init(ObjectMap, hInstance, &LIBID_MULTIFACELib); 32 | DisableThreadLibraryCalls(hInstance); 33 | } 34 | else if (dwReason == DLL_PROCESS_DETACH) 35 | _Module.Term(); 36 | return TRUE; // ok 37 | } 38 | 39 | ///////////////////////////////////////////////////////////////////////////// 40 | // Used to determine whether the DLL can be unloaded by OLE 41 | 42 | STDAPI DllCanUnloadNow(void) 43 | { 44 | return (_Module.GetLockCount()==0) ? S_OK : S_FALSE; 45 | } 46 | 47 | ///////////////////////////////////////////////////////////////////////////// 48 | // Returns a class factory to create an object of the requested type 49 | 50 | STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) 51 | { 52 | return _Module.GetClassObject(rclsid, riid, ppv); 53 | } 54 | 55 | ///////////////////////////////////////////////////////////////////////////// 56 | // DllRegisterServer - Adds entries to the system registry 57 | 58 | STDAPI DllRegisterServer(void) 59 | { 60 | // registers object, typelib and all interfaces in typelib 61 | return _Module.RegisterServer(TRUE); 62 | } 63 | 64 | ///////////////////////////////////////////////////////////////////////////// 65 | // DllUnregisterServer - Removes entries from the system registry 66 | 67 | STDAPI DllUnregisterServer(void) 68 | { 69 | return _Module.UnregisterServer(TRUE); 70 | } 71 | 72 | 73 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFace.def: -------------------------------------------------------------------------------- 1 | ; MultiFace.def : Declares the module parameters. 2 | 3 | LIBRARY "MultiFace.DLL" 4 | 5 | EXPORTS 6 | DllCanUnloadNow @1 PRIVATE 7 | DllGetClassObject @2 PRIVATE 8 | DllRegisterServer @3 PRIVATE 9 | DllUnregisterServer @4 PRIVATE 10 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFace.dsw: -------------------------------------------------------------------------------- 1 | Microsoft Developer Studio Workspace File, Format Version 6.00 2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! 3 | 4 | ############################################################################### 5 | 6 | Project: "MultiFace"=.\MultiFace.dsp - Package Owner=<4> 7 | 8 | Package=<5> 9 | {{{ 10 | }}} 11 | 12 | Package=<4> 13 | {{{ 14 | }}} 15 | 16 | ############################################################################### 17 | 18 | Global: 19 | 20 | Package=<5> 21 | {{{ 22 | }}} 23 | 24 | Package=<3> 25 | {{{ 26 | }}} 27 | 28 | ############################################################################### 29 | 30 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFace.idl: -------------------------------------------------------------------------------- 1 | // MultiFace.idl : IDL source for MultiFace.dll 2 | // 3 | 4 | // This file will be processed by the MIDL tool to 5 | // produce the type library (MultiFace.tlb) and marshalling code. 6 | 7 | import "oaidl.idl"; 8 | import "ocidl.idl"; 9 | 10 | [ 11 | object, 12 | uuid(9BF2440F-B2E0-11D4-A695-00104BFF3241), 13 | dual, 14 | helpstring("IFace1 Interface"), 15 | pointer_default(unique) 16 | ] 17 | interface IFace1 : IDispatch 18 | { 19 | [propget, id(1), helpstring("property Face1Name")] HRESULT Face1Name([out, retval] BSTR *pVal); 20 | [propput, id(1), helpstring("property Face1Name")] HRESULT Face1Name([in] BSTR newVal); 21 | }; 22 | 23 | [ 24 | object, 25 | uuid(9BF24410-B2E0-11D4-A695-00104BFF3241), 26 | dual, 27 | helpstring("IFace2 Interface"), 28 | pointer_default(unique) 29 | ] 30 | interface IFace2 : IDispatch 31 | { 32 | [propget, id(1), helpstring("property Face2Nam")] HRESULT Face2Nam([out, retval] BSTR *pVal); 33 | [propput, id(1), helpstring("property Face2Nam")] HRESULT Face2Nam([in] BSTR newVal); 34 | }; 35 | 36 | [ 37 | object, 38 | uuid(9BF24411-B2E0-11D4-A695-00104BFF3241), 39 | dual, 40 | helpstring("IFace3 Interface"), 41 | pointer_default(unique) 42 | ] 43 | interface IFace3 : IDispatch 44 | { 45 | [propget, id(1), helpstring("property Face3Name")] HRESULT Face3Name([out, retval] BSTR *pVal); 46 | [propput, id(1), helpstring("property Face3Name")] HRESULT Face3Name([in] BSTR newVal); 47 | }; 48 | 49 | [ 50 | uuid(9BF24403-B2E0-11D4-A695-00104BFF3241), 51 | version(1.0), 52 | helpstring("MultiFace 1.0 Type Library") 53 | ] 54 | library MULTIFACELib 55 | { 56 | importlib("stdole32.tlb"); 57 | importlib("stdole2.tlb"); 58 | 59 | 60 | [ 61 | uuid(9BF24412-B2E0-11D4-A695-00104BFF3241), 62 | helpstring("Face Class") 63 | ] 64 | coclass Face 65 | { 66 | [default] interface IFace1; 67 | interface IFace2; 68 | interface IFace3; 69 | }; 70 | }; 71 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFace.ncb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/samples/com/jacob/samples/atl/MultiFace/MultiFace.ncb -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFace.opt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/samples/com/jacob/samples/atl/MultiFace/MultiFace.opt -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFace.plg: -------------------------------------------------------------------------------- 1 | 2 | 3 |
 4 | 

Build Log

5 |

6 | --------------------Configuration: MultiFace - Win32 Debug-------------------- 7 |

8 |

Command Lines

9 | Creating temporary file "C:\TEMP\RSP335.tmp" with contents 10 | [ 11 | /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Fp"Debug/MultiFace.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 12 | "D:\jacob_15\samples\test\atl\MultiFace\MultiFace.cpp" 13 | "D:\jacob_15\samples\test\atl\MultiFace\Face.cpp" 14 | ] 15 | Creating command line "cl.exe @C:\TEMP\RSP335.tmp" 16 | Creating temporary file "C:\TEMP\RSP336.tmp" with contents 17 | [ 18 | kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"Debug/MultiFace.pdb" /debug /machine:I386 /def:".\MultiFace.def" /out:"Debug/MultiFace.dll" /implib:"Debug/MultiFace.lib" /pdbtype:sept 19 | .\Debug\StdAfx.obj 20 | .\Debug\MultiFace.obj 21 | .\Debug\MultiFace.res 22 | .\Debug\Face.obj 23 | ] 24 | Creating command line "link.exe @C:\TEMP\RSP336.tmp" 25 | Creating temporary file "C:\TEMP\RSP337.bat" with contents 26 | [ 27 | @echo off 28 | regsvr32 /s /c ".\Debug\MultiFace.dll" 29 | echo regsvr32 exec. time > ".\Debug\regsvr32.trg" 30 | ] 31 | Creating command line "C:\TEMP\RSP337.bat" 32 | Compiling... 33 | MultiFace.cpp 34 | Face.cpp 35 | Generating Code... 36 | Linking... 37 |

Output Window

38 | Performing registration 39 | RegSvr32: DllRegisterServer in .\Debug\MultiFace.dll succeeded. 40 | 41 | 42 | 43 | 44 |

Results

45 | MultiFace.dll - 0 error(s), 0 warning(s) 46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFace.rc: -------------------------------------------------------------------------------- 1 | //Microsoft Developer Studio generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "winres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE DISCARDABLE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE DISCARDABLE 36 | BEGIN 37 | "#include ""winres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE DISCARDABLE 42 | BEGIN 43 | "1 TYPELIB ""MultiFace.tlb""\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | #ifndef _MAC 51 | ///////////////////////////////////////////////////////////////////////////// 52 | // 53 | // Version 54 | // 55 | 56 | VS_VERSION_INFO VERSIONINFO 57 | FILEVERSION 1,0,0,1 58 | PRODUCTVERSION 1,0,0,1 59 | FILEFLAGSMASK 0x3fL 60 | #ifdef _DEBUG 61 | FILEFLAGS 0x1L 62 | #else 63 | FILEFLAGS 0x0L 64 | #endif 65 | FILEOS 0x4L 66 | FILETYPE 0x2L 67 | FILESUBTYPE 0x0L 68 | BEGIN 69 | BLOCK "StringFileInfo" 70 | BEGIN 71 | BLOCK "040904B0" 72 | BEGIN 73 | VALUE "CompanyName", "\0" 74 | VALUE "FileDescription", "MultiFace Module\0" 75 | VALUE "FileVersion", "1, 0, 0, 1\0" 76 | VALUE "InternalName", "MultiFace\0" 77 | VALUE "LegalCopyright", "Copyright 2000\0" 78 | VALUE "OriginalFilename", "MultiFace.DLL\0" 79 | VALUE "ProductName", "MultiFace Module\0" 80 | VALUE "ProductVersion", "1, 0, 0, 1\0" 81 | VALUE "OLESelfRegister", "\0" 82 | END 83 | END 84 | BLOCK "VarFileInfo" 85 | BEGIN 86 | VALUE "Translation", 0x409, 1200 87 | END 88 | END 89 | 90 | #endif // !_MAC 91 | 92 | 93 | ///////////////////////////////////////////////////////////////////////////// 94 | // 95 | // REGISTRY 96 | // 97 | 98 | IDR_Face REGISTRY DISCARDABLE "Face.rgs" 99 | 100 | ///////////////////////////////////////////////////////////////////////////// 101 | // 102 | // String Table 103 | // 104 | 105 | STRINGTABLE DISCARDABLE 106 | BEGIN 107 | IDS_PROJNAME "MultiFace" 108 | IDS_FACE_DESC "Face Class" 109 | END 110 | 111 | #endif // English (U.S.) resources 112 | ///////////////////////////////////////////////////////////////////////////// 113 | 114 | 115 | 116 | #ifndef APSTUDIO_INVOKED 117 | ///////////////////////////////////////////////////////////////////////////// 118 | // 119 | // Generated from the TEXTINCLUDE 3 resource. 120 | // 121 | 1 TYPELIB "MultiFace.tlb" 122 | 123 | ///////////////////////////////////////////////////////////////////////////// 124 | #endif // not APSTUDIO_INVOKED 125 | 126 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFace.tlb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/samples/com/jacob/samples/atl/MultiFace/MultiFace.tlb -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFace_i.c: -------------------------------------------------------------------------------- 1 | /* this file contains the actual definitions of */ 2 | /* the IIDs and CLSIDs */ 3 | 4 | /* link this file in with the server and any clients */ 5 | 6 | 7 | /* File created by MIDL compiler version 5.01.0164 */ 8 | /* at Sun Nov 05 01:12:47 2000 9 | */ 10 | /* Compiler settings for D:\jacob_15\samples\test\atl\MultiFace\MultiFace.idl: 11 | Oicf (OptLev=i2), W1, Zp8, env=Win32, ms_ext, c_ext 12 | error checks: allocation ref bounds_check enum stub_data 13 | */ 14 | //@@MIDL_FILE_HEADING( ) 15 | #ifdef __cplusplus 16 | extern "C"{ 17 | #endif 18 | 19 | 20 | #ifndef __IID_DEFINED__ 21 | #define __IID_DEFINED__ 22 | 23 | typedef struct _IID 24 | { 25 | unsigned long x; 26 | unsigned short s1; 27 | unsigned short s2; 28 | unsigned char c[8]; 29 | } IID; 30 | 31 | #endif // __IID_DEFINED__ 32 | 33 | #ifndef CLSID_DEFINED 34 | #define CLSID_DEFINED 35 | typedef IID CLSID; 36 | #endif // CLSID_DEFINED 37 | 38 | const IID IID_IFace1 = {0x9BF2440F,0xB2E0,0x11D4,{0xA6,0x95,0x00,0x10,0x4B,0xFF,0x32,0x41}}; 39 | 40 | 41 | const IID IID_IFace2 = {0x9BF24410,0xB2E0,0x11D4,{0xA6,0x95,0x00,0x10,0x4B,0xFF,0x32,0x41}}; 42 | 43 | 44 | const IID IID_IFace3 = {0x9BF24411,0xB2E0,0x11D4,{0xA6,0x95,0x00,0x10,0x4B,0xFF,0x32,0x41}}; 45 | 46 | 47 | const IID LIBID_MULTIFACELib = {0x9BF24403,0xB2E0,0x11D4,{0xA6,0x95,0x00,0x10,0x4B,0xFF,0x32,0x41}}; 48 | 49 | 50 | const CLSID CLSID_Face = {0x9BF24412,0xB2E0,0x11D4,{0xA6,0x95,0x00,0x10,0x4B,0xFF,0x32,0x41}}; 51 | 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFaceps.def: -------------------------------------------------------------------------------- 1 | 2 | LIBRARY "MultiFacePS" 3 | 4 | DESCRIPTION 'Proxy/Stub DLL' 5 | 6 | EXPORTS 7 | DllGetClassObject @1 PRIVATE 8 | DllCanUnloadNow @2 PRIVATE 9 | GetProxyDllInfo @3 PRIVATE 10 | DllRegisterServer @4 PRIVATE 11 | DllUnregisterServer @5 PRIVATE 12 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/MultiFaceps.mk: -------------------------------------------------------------------------------- 1 | 2 | MultiFaceps.dll: dlldata.obj MultiFace_p.obj MultiFace_i.obj 3 | link /dll /out:MultiFaceps.dll /def:MultiFaceps.def /entry:DllMain dlldata.obj MultiFace_p.obj MultiFace_i.obj \ 4 | kernel32.lib rpcndr.lib rpcns4.lib rpcrt4.lib oleaut32.lib uuid.lib \ 5 | 6 | .c.obj: 7 | cl /c /Ox /DWIN32 /D_WIN32_WINNT=0x0400 /DREGISTER_PROXY_DLL \ 8 | $< 9 | 10 | clean: 11 | @del MultiFaceps.dll 12 | @del MultiFaceps.lib 13 | @del MultiFaceps.exp 14 | @del dlldata.obj 15 | @del MultiFace_p.obj 16 | @del MultiFace_i.obj 17 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/StdAfx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // stdafx.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | #ifdef _ATL_STATIC_REGISTRY 8 | #include 9 | #include 10 | #endif 11 | 12 | #include 13 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/StdAfx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, 3 | // but are changed infrequently 4 | 5 | #if !defined(AFX_STDAFX_H__9BF24406_B2E0_11D4_A695_00104BFF3241__INCLUDED_) 6 | #define AFX_STDAFX_H__9BF24406_B2E0_11D4_A695_00104BFF3241__INCLUDED_ 7 | 8 | #if _MSC_VER > 1000 9 | #pragma once 10 | #endif // _MSC_VER > 1000 11 | 12 | #define STRICT 13 | #ifndef _WIN32_WINNT 14 | #define _WIN32_WINNT 0x0400 15 | #endif 16 | #define _ATL_APARTMENT_THREADED 17 | 18 | #include 19 | //You may derive a class from CComModule and use it if you want to override 20 | //something, but do not change the name of _Module 21 | extern CComModule _Module; 22 | #include 23 | 24 | //{{AFX_INSERT_LOCATION}} 25 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line. 26 | 27 | #endif // !defined(AFX_STDAFX_H__9BF24406_B2E0_11D4_A695_00104BFF3241__INCLUDED) 28 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/dlldata.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | DllData file -- generated by MIDL compiler 3 | 4 | DO NOT ALTER THIS FILE 5 | 6 | This file is regenerated by MIDL on every IDL file compile. 7 | 8 | To completely reconstruct this file, delete it and rerun MIDL 9 | on all the IDL files in this DLL, specifying this file for the 10 | /dlldata command line option 11 | 12 | *********************************************************/ 13 | 14 | #define PROXY_DELEGATION 15 | 16 | #include 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | EXTERN_PROXY_FILE( MultiFace ) 23 | 24 | 25 | PROXYFILE_LIST_START 26 | /* Start of list */ 27 | REFERENCE_PROXY_FILE( MultiFace ), 28 | /* End of list */ 29 | PROXYFILE_LIST_END 30 | 31 | 32 | DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID ) 33 | 34 | #ifdef __cplusplus 35 | } /*extern "C" */ 36 | #endif 37 | 38 | /* end of generated dlldata file */ 39 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFace/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Developer Studio generated include file. 3 | // Used by MultiFace.rc 4 | // 5 | #define IDS_PROJNAME 100 6 | #define IDS_FACE_DESC 101 7 | #define IDR_Face 102 8 | 9 | // Next default values for new objects 10 | // 11 | #ifdef APSTUDIO_INVOKED 12 | #ifndef APSTUDIO_READONLY_SYMBOLS 13 | #define _APS_NEXT_RESOURCE_VALUE 201 14 | #define _APS_NEXT_COMMAND_VALUE 32768 15 | #define _APS_NEXT_CONTROL_VALUE 201 16 | #define _APS_NEXT_SYMED_VALUE 103 17 | #endif 18 | #endif 19 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/MultiFaceTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.atl; 2 | 3 | import com.jacob.activeX.ActiveXComponent; 4 | import com.jacob.com.Dispatch; 5 | import com.jacob.com.Variant; 6 | 7 | class MultiFaceTest { 8 | 9 | /** 10 | * standard main() test program 11 | * 12 | * @param args 13 | * the command line arguments 14 | */ 15 | public static void main(String[] args) { 16 | // this method has been deprecated as being unreliable. 17 | // shutdown should be done through other means 18 | // whoever wrote this example should explain what this was intended to 19 | // do 20 | // System.runFinalizersOnExit(true); 21 | 22 | ActiveXComponent mf = new ActiveXComponent("MultiFace.Face"); 23 | try { 24 | // I am now dealing with the default interface (IFace1) 25 | Dispatch.put(mf, "Face1Name", new Variant("Hello Face1")); 26 | System.out.println(Dispatch.get(mf, "Face1Name")); 27 | 28 | // get to IFace2 through the IID 29 | Dispatch f2 = mf 30 | .QueryInterface("{9BF24410-B2E0-11D4-A695-00104BFF3241}"); 31 | // I am now dealing with IFace2 32 | Dispatch.put(f2, "Face2Nam", new Variant("Hello Face2")); 33 | System.out.println(Dispatch.get(f2, "Face2Nam")); 34 | 35 | // get to IFace3 through the IID 36 | Dispatch f3 = mf 37 | .QueryInterface("{9BF24411-B2E0-11D4-A695-00104BFF3241}"); 38 | // I am now dealing with IFace3 39 | Dispatch.put(f3, "Face3Name", new Variant("Hello Face3")); 40 | System.out.println(Dispatch.get(f3, "Face3Name")); 41 | 42 | } catch (Exception e) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/atl/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates how to access multiple interfaces. 2 | 3 | To run it, chdir to MultiFace\Debug and run: 4 | ``` 5 | regsvr32 MultiFace.dll 6 | ``` 7 | Then, run (in this dir): 8 | ``` 9 | java MultiFace 10 | ``` 11 | 12 | As you can see from MultiFace\MultiFace.idl - there are 3 interfaces. 13 | 14 | By default JACOB attaches to the default interface. 15 | 16 | The file MultiFace.java shows how to use the new Dispatch.QueryInterface 17 | to get access to the other interfaces. 18 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/office/ExcelDispatchTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.office; 2 | 3 | import com.jacob.activeX.ActiveXComponent; 4 | import com.jacob.com.ComThread; 5 | import com.jacob.com.Dispatch; 6 | import com.jacob.com.Variant; 7 | 8 | /** 9 | * Sample test program snagged out of a question on the sun discussion area. 10 | *

11 | * May need to run with some command line options (including from inside 12 | * Eclipse). Look in the docs area at the Jacob usage document for command line 13 | * options. 14 | */ 15 | public class ExcelDispatchTest { 16 | 17 | /** 18 | * main run loop for test program 19 | * 20 | * @param args 21 | * standard command line arguments 22 | */ 23 | public static void main(String[] args) { 24 | ComThread.InitSTA(); 25 | 26 | ActiveXComponent xl = new ActiveXComponent("Excel.Application"); 27 | try { 28 | System.out.println("version=" + xl.getProperty("Version")); 29 | System.out.println("version=" + Dispatch.get(xl, "Version")); 30 | Dispatch.put(xl, "Visible", new Variant(true)); 31 | Dispatch workbooks = xl.getProperty("Workbooks").toDispatch(); 32 | Dispatch workbook = Dispatch.get(workbooks, "Add").toDispatch(); 33 | Dispatch sheet = Dispatch.get(workbook, "ActiveSheet").toDispatch(); 34 | Dispatch a1 = Dispatch.invoke(sheet, "Range", Dispatch.Get, 35 | new Object[] { "A1" }, new int[1]).toDispatch(); 36 | Dispatch a2 = Dispatch.invoke(sheet, "Range", Dispatch.Get, 37 | new Object[] { "A2" }, new int[1]).toDispatch(); 38 | Dispatch.put(a1, "Value", "123.456"); 39 | Dispatch.put(a2, "Formula", "=A1*2"); 40 | System.out.println("a1 from excel:" + Dispatch.get(a1, "Value")); 41 | System.out.println("a2 from excel:" + Dispatch.get(a2, "Value")); 42 | Variant f = new Variant(false); 43 | Dispatch.call(workbook, "Close", f); 44 | } catch (Exception e) { 45 | e.printStackTrace(); 46 | } finally { 47 | xl.invoke("Quit", new Variant[] {}); 48 | ComThread.Release(); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/office/TestDocument.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/samples/com/jacob/samples/office/TestDocument.doc -------------------------------------------------------------------------------- /samples/com/jacob/samples/office/VisioPrintTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.office; 2 | 3 | import com.jacob.activeX.ActiveXComponent; 4 | import com.jacob.com.ComFailException; 5 | import com.jacob.com.Dispatch; 6 | 7 | /** 8 | * Snippet to show Visio print dialog 9 | *

10 | * Sample submitted by fatbuttlarry in SourceForge 1803140 as part of bug report 11 | *

12 | * Tested with Java 6.0SE and MS Office 2003 ** Note: 1010 = VB's 13 | * visCmdFilePrint constant 14 | */ 15 | public class VisioPrintTest { 16 | 17 | /** 18 | * Runs the print ant lets the user say ok or cancel. Note the funky Visio 19 | * behavior if someone hits the cancel button 20 | * 21 | */ 22 | public void testPrintDialog() { 23 | ActiveXComponent oActiveX = new ActiveXComponent("Visio.Application"); 24 | Dispatch oDocuments = oActiveX.getProperty("Documents").toDispatch(); 25 | // create a blank document 26 | Dispatch.call(oDocuments, "Add", ""); 27 | try { 28 | Dispatch.call(oActiveX, "DoCmd", new Integer(1010)).getInt(); 29 | System.out.println("User hit the ok button."); 30 | } catch (ComFailException e) { 31 | System.out.println("User hit the cancel button: " + e); 32 | } finally { 33 | oActiveX.invoke("Quit"); 34 | } 35 | return; 36 | } 37 | 38 | /** 39 | * quick main() to test this 40 | * 41 | * @param args 42 | * standard command line arguments 43 | */ 44 | public static void main(String[] args) { 45 | VisioPrintTest testObject = new VisioPrintTest(); 46 | testObject.testPrintDialog(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/office/~$stDocument.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/samples/com/jacob/samples/office/~$stDocument.doc -------------------------------------------------------------------------------- /samples/com/jacob/samples/outlook/Outlook.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.outlook; 2 | 3 | /** 4 | * JACOB Outlook sample contributed by 5 | * Christopher Brind 6 | */ 7 | 8 | import com.jacob.activeX.ActiveXComponent; 9 | import com.jacob.com.Dispatch; 10 | import com.jacob.com.Variant; 11 | 12 | /** 13 | * sample class to show simple outlook manipulation 14 | */ 15 | public class Outlook { 16 | 17 | private static String pad(int i) { 18 | StringBuffer sb = new StringBuffer(); 19 | 20 | while (sb.length() < i) { 21 | sb.append(' '); 22 | } 23 | 24 | return sb.toString(); 25 | } 26 | 27 | private static void recurseFolders(int iIndent, Dispatch o) { 28 | 29 | if (o == null) { 30 | return; 31 | } 32 | Dispatch oFolders = Dispatch.get(o, "Folders").toDispatch(); 33 | // System.out.println("oFolders=" + oFolders); 34 | if (oFolders == null) { 35 | return; 36 | } 37 | 38 | Dispatch oFolder = Dispatch.get(oFolders, "GetFirst").toDispatch(); 39 | do { 40 | Object oFolderName = Dispatch.get(oFolder, "Name"); 41 | if (null == oFolderName) { 42 | break; 43 | } 44 | 45 | System.out.println(pad(iIndent) + oFolderName); 46 | recurseFolders(iIndent + 3, oFolder); 47 | 48 | oFolder = Dispatch.get(oFolders, "GetNext").toDispatch(); 49 | } while (true); 50 | 51 | } 52 | 53 | /** 54 | * standard run loop 55 | * 56 | * @param asArgs 57 | * command line arguments 58 | * @throws Exception 59 | */ 60 | public static void main(String asArgs[]) throws Exception { 61 | System.out.println("Outlook: IN"); 62 | 63 | ActiveXComponent axOutlook = new ActiveXComponent("Outlook.Application"); 64 | try { 65 | System.out.println("version=" + axOutlook.getProperty("Version")); 66 | 67 | Dispatch oOutlook = axOutlook.getObject(); 68 | System.out.println("version=" + Dispatch.get(oOutlook, "Version")); 69 | 70 | Dispatch oNameSpace = axOutlook.getProperty("Session").toDispatch(); 71 | System.out.println("oNameSpace=" + oNameSpace); 72 | 73 | recurseFolders(0, oNameSpace); 74 | 75 | } finally { 76 | axOutlook.invoke("Quit", new Variant[] {}); 77 | } 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/servlet/JacobScript.java_nocompile: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.servlet; 2 | 3 | import javax.servlet.*; 4 | import javax.servlet.http.*; 5 | import java.io.*; 6 | 7 | import com.jacob.com.*; 8 | import com.jacob.activeX.*; 9 | 10 | public class JacobScript extends javax.servlet.http.HttpServlet 11 | { 12 | public void doGet(HttpServletRequest req, 13 | HttpServletResponse res) 14 | throws ServletException 15 | { 16 | PrintWriter out = null; 17 | try 18 | { 19 | res.setContentType("text/html"); 20 | out = res.getWriter(); 21 | // display a form 22 | out.println("

Enter a VBScript Expression

"); 23 | out.println("
"); 24 | out.println(""); 25 | out.println(""); 26 | out.println("
"); 27 | } catch (Exception e) { 28 | e.printStackTrace(); 29 | out.println("

Error:"+e+"

"); 30 | } 31 | } 32 | 33 | public void doPost(HttpServletRequest req, 34 | HttpServletResponse res) 35 | throws ServletException 36 | { 37 | PrintWriter out = null; 38 | 39 | try 40 | { 41 | res.setContentType("text/html"); 42 | out = res.getWriter(); 43 | // get what they typed in 44 | String expr = (String)req.getParameter("expr"); 45 | // make sure we have a session 46 | HttpSession session = req.getSession(true); 47 | Dispatch sControl = null; 48 | if (session.isNew()) 49 | { 50 | // initialize the control and store it on the session 51 | String lang = "VBScript"; 52 | ActiveXComponent sC = new ActiveXComponent("ScriptControl"); 53 | sControl = sC.getObject(); 54 | Dispatch.put(sControl, "Language", lang); 55 | session.putValue("control", sControl); 56 | } 57 | else 58 | { 59 | sControl = (Dispatch)session.getValue("control"); 60 | } 61 | Variant result = Dispatch.call(sControl, "Eval", expr); 62 | // display a form 63 | out.println("

Enter a VBScript Expression

"); 64 | out.println("
"); 65 | out.println(""); 66 | out.println(""); 67 | out.println("
"); 68 | out.println("

Jacob Response:

"); 69 | out.println("

"+result+"

"); 70 | } catch (Exception e) { 71 | e.printStackTrace(); 72 | out.println("

Error:"+e+"

"); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/servlet/README.md: -------------------------------------------------------------------------------- 1 | This sample runs in Weblogic 5.1 as a servlet. 2 | 3 | 0. Rename JacobScript.java_nocompile to JacobScript.java 4 | 1. Compile this file (make sure you have jdk1.2 installed or the 5 | javax.servlet.* classes in your classpath). 6 | 2. Make sure the weblogic policy file allows native access. The easiest 7 | way is to replace the contents with this: 8 | 9 | ``` 10 | grant codeBase "file:d:/weblogic/-" { 11 | permission java.security.AllPermission; 12 | }; 13 | 14 | grant codeBase "file:/c:/classes/-" { 15 | permission java.security.AllPermission; 16 | }; 17 | 18 | 19 | grant codeBase "file:${java.home}/lib/ext/-" { 20 | permission java.security.AllPermission; 21 | }; 22 | 23 | grant { 24 | permission java.security.AllPermission; 25 | }; 26 | ``` 27 | 28 | 3. Add the servlet to the weblogic.properties file: 29 | 30 | ``` 31 | weblogic.httpd.register.JacobScript=JacobScript 32 | ``` 33 | 34 | 4. Either add your CLASSPATH to weblogic.classpath in startWebLogic.cmd 35 | or copy the com directory into weblogic/myserver/servletclasses 36 | 37 | 5. Copy the jacob/samples/servlet/* into weblogic/myserver/servletclasses 38 | 6. Start weblogic 39 | 40 | 7. Type the url: http://localhost:7001/JacobScript into the browser 41 | (If you run on port 7001) 42 | 43 | 8. Enter a VBScript expression like: 44 | 1+2 45 | Now 46 | "hello" & " world" 47 | etc. 48 | and watch the MS Script control (which you must have installed) 49 | evaluate and return the result. 50 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/system/SystemMonitor.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.system; 2 | 3 | import com.jacob.activeX.ActiveXComponent; 4 | import com.jacob.com.Dispatch; 5 | import com.jacob.com.EnumVariant; 6 | import com.jacob.com.Variant; 7 | 8 | /** 9 | * Sample program that shows how to talk to WMI on local machine. 10 | * 11 | * This test program was derived from SourceForge question 12 | * http://sourceforge.net/forum/forum.php?thread_id=1831650&forum_id=375946 13 | * fold, spindled and mutilated by clay_shooter 14 | * 15 | * @author chris_knowles 16 | * 17 | */ 18 | public class SystemMonitor { 19 | 20 | /** 21 | * example run loop method called by main() 22 | */ 23 | public void runMonitor() { 24 | 25 | ActiveXComponent wmi = null; 26 | wmi = new ActiveXComponent("WbemScripting.SWbemLocator"); 27 | // no connection parameters means to connect to the local machine 28 | Variant conRet = wmi.invoke("ConnectServer"); 29 | // the author liked the ActiveXComponent api style over the Dispatch 30 | // style 31 | ActiveXComponent wmiconnect = new ActiveXComponent(conRet.toDispatch()); 32 | 33 | // the WMI supports a query language. 34 | String query = "select CategoryString, Message, TimeGenerated, User, Type " 35 | + "from Win32_NtLogEvent " 36 | + "where Logfile = 'Application' and TimeGenerated > '20070915000000.000000-***'"; 37 | Variant vCollection = wmiconnect 38 | .invoke("ExecQuery", new Variant(query)); 39 | 40 | EnumVariant enumVariant = new EnumVariant(vCollection.toDispatch()); 41 | 42 | String resultString = ""; 43 | Dispatch item = null; 44 | 45 | while (enumVariant.hasMoreElements()) { 46 | resultString = ""; 47 | item = enumVariant.nextElement().toDispatch(); 48 | String categoryString = Dispatch.call(item, "CategoryString") 49 | .toString(); 50 | String messageString = Dispatch.call(item, "Message").toString(); 51 | String timeGenerated = Dispatch.call(item, "TimeGenerated") 52 | .toString(); 53 | String eventUser = Dispatch.call(item, "User").toString(); 54 | String eventType = Dispatch.call(item, "Type").toString(); 55 | resultString += "TimeGenerated: " + timeGenerated + " Category: " 56 | + categoryString + " User: " + eventUser + " EventType: " 57 | + eventType + " Message:" + messageString; 58 | System.out.println(resultString); 59 | 60 | } 61 | 62 | } 63 | 64 | /** 65 | * sample's main program 66 | * 67 | * @param args 68 | * command line arguments 69 | */ 70 | public static void main(String[] args) { 71 | SystemMonitor utilConnection = new SystemMonitor(); 72 | utilConnection.runMonitor(); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/visio/VisioApp.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.visio; 2 | 3 | import java.io.File; 4 | 5 | import com.jacob.activeX.ActiveXComponent; 6 | import com.jacob.com.DispatchEvents; 7 | import com.jacob.com.Variant; 8 | 9 | /** 10 | * Created as part of sourceforge 1386454 to demonstrate returning values in 11 | * event handlers 12 | * 13 | * @author miles@rowansoftware.net 14 | * 15 | * This class represents the visio app itself 16 | */ 17 | public class VisioApp extends ActiveXComponent { 18 | 19 | /** 20 | * constructor that spins up Visio 21 | * 22 | * @throws VisioException 23 | */ 24 | public VisioApp() throws VisioException { 25 | super("Visio.Application"); 26 | setVisible(false); 27 | } 28 | 29 | /** 30 | * creates a DispatchEvents object to register o as a listener 31 | * 32 | * @param o 33 | */ 34 | public void addEventListener(VisioEventListener o) { 35 | DispatchEvents events = new DispatchEvents(this, o); 36 | if (events == null) { 37 | System.out 38 | .println("You should never get null back when creating a DispatchEvents object"); 39 | } 40 | } 41 | 42 | /** 43 | * opens the passed in file in Visio 44 | * 45 | * @param f 46 | * @throws VisioException 47 | */ 48 | public void open(File f) throws VisioException { 49 | try { 50 | ActiveXComponent documents = new ActiveXComponent(getProperty( 51 | "Documents").toDispatch()); 52 | Variant[] args = new Variant[1]; 53 | args[0] = new Variant(f.getPath()); 54 | documents.invoke("Open", args); 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | throw new VisioException(e); 58 | } 59 | } 60 | 61 | /** 62 | * tells Visio to save the drawing 63 | * 64 | * @throws VisioException 65 | */ 66 | public void save() throws VisioException { 67 | try { 68 | ActiveXComponent document = new ActiveXComponent(getProperty( 69 | "ActiveDocument").toDispatch()); 70 | document.invoke("Save"); 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | throw new VisioException(e); 74 | } 75 | } 76 | 77 | /** 78 | * terminates Visio 79 | */ 80 | public void quit() { 81 | System.out.println("Received quit()"); 82 | // there can't be any open documents for this to work 83 | // you'll get a visio error if you don't close them 84 | ActiveXComponent document = new ActiveXComponent(getProperty( 85 | "ActiveDocument").toDispatch()); 86 | document.invoke("Close"); 87 | invoke("Quit"); 88 | } 89 | 90 | /** 91 | * runs the Visio export command 92 | * 93 | * @param f 94 | * @throws VisioException 95 | */ 96 | public void export(File f) throws VisioException { 97 | try { 98 | ActiveXComponent document = new ActiveXComponent(getProperty( 99 | "ActivePage").toDispatch()); 100 | Variant[] args = new Variant[1]; 101 | args[0] = new Variant(f.getPath()); 102 | document.invoke("Export", args); 103 | } catch (Exception e) { 104 | throw new VisioException(e); 105 | } 106 | } 107 | 108 | /** 109 | * makes Visio visible so the user can watch 110 | * 111 | * @param b 112 | * @throws VisioException 113 | */ 114 | public void setVisible(boolean b) throws VisioException { 115 | try { 116 | setProperty("Visible", new Variant(b)); 117 | } catch (Exception e) { 118 | throw new VisioException(e); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/visio/VisioEventAdapter.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.visio; 2 | 3 | import com.jacob.com.Variant; 4 | 5 | /** 6 | * Created as part of sourceforge 1386454 to demonstrate returning values in 7 | * event handlers 8 | * 9 | * @author miles@rowansoftware.net 10 | * 11 | * You can subclass this class and only implement the methods you're interested 12 | * in 13 | */ 14 | public class VisioEventAdapter implements VisioEventListener { 15 | 16 | VisioApp app = null; 17 | 18 | public VisioEventAdapter(VisioApp pApp) { 19 | app = pApp; 20 | System.out.println("Event listener constructed"); 21 | } 22 | 23 | public void BeforeQuit(Variant[] args) { 24 | } 25 | 26 | public void DocumentChanged(Variant[] args) { 27 | System.out.println("documentChanged()"); 28 | } 29 | 30 | public void DocumentCloseCanceled(Variant[] args) { 31 | } 32 | 33 | public void DocumentCreated(Variant[] args) { 34 | } 35 | 36 | public void DocumentOpened(Variant[] args) { 37 | System.out.println("DocumentOpened()"); 38 | } 39 | 40 | public void DocumentSaved(Variant[] args) { 41 | } 42 | 43 | public void DocumentSavedAs(Variant[] args) { 44 | } 45 | 46 | public Variant QueryCancelDocumentClose(Variant[] args) { 47 | System.out.println("QueryCancelDocumentClose()"); 48 | return new Variant(false); 49 | } 50 | 51 | /** 52 | * we don't actually let it quit. We block it so that we don't have to 53 | * relaunch when we look at a new document 54 | */ 55 | public Variant QueryCancelQuit(Variant[] args) { 56 | // these may throw VisioException 57 | System.out 58 | .println("Saving document, hiding and telling visio not to quit"); 59 | try { 60 | app.save(); 61 | app.setVisible(false); 62 | } catch (VisioException ve) { 63 | System.out.println("ailed to openFile()"); 64 | ve.printStackTrace(); 65 | } 66 | return new Variant(true); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/visio/VisioEventListener.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.visio; 2 | 3 | import com.jacob.com.Variant; 4 | 5 | /** 6 | * Created as part of sourceforge 1386454 to demonstrate returning values in 7 | * event handlers 8 | * 9 | * @author miles@rowansoftware.net 10 | * 11 | * There are many more Visio events available. See the Microsoft Office SDK 12 | * documentation. To receive an event, add a method to this interface whose name 13 | * matches the event name and has only one parameter, Variant[]. The JACOB 14 | * library will use reflection to call that method when an event is received. 15 | */ 16 | public interface VisioEventListener { 17 | 18 | public void BeforeQuit(Variant[] args); 19 | 20 | public void DocumentChanged(Variant[] args); 21 | 22 | public void DocumentCloseCanceled(Variant[] args); 23 | 24 | public void DocumentCreated(Variant[] args); 25 | 26 | public void DocumentOpened(Variant[] args); 27 | 28 | public void DocumentSaved(Variant[] args); 29 | 30 | public void DocumentSavedAs(Variant[] args); 31 | 32 | public Variant QueryCancelQuit(Variant[] args); 33 | } 34 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/visio/VisioException.java: -------------------------------------------------------------------------------- 1 | package com.jacob.samples.visio; 2 | 3 | /** 4 | * Created as part of sourceforge 1386454 to demonstrate returning values in 5 | * event handlers 6 | * 7 | * @author miles@rowansoftware.net 8 | * 9 | * This extends runtime exception so that we can be sloppy and not put catch 10 | * blocks everywhere 11 | */ 12 | public class VisioException extends Exception { 13 | /** 14 | * Totally dummy value to make Eclipse quit complaining 15 | */ 16 | private static final long serialVersionUID = 1L; 17 | 18 | public VisioException(String msg) { 19 | super(msg); 20 | } 21 | 22 | public VisioException(Throwable cause) { 23 | super(cause); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/com/jacob/samples/visio/test_drawing.vsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/samples/com/jacob/samples/visio/test_drawing.vsd -------------------------------------------------------------------------------- /src/jni/.cvsignore: -------------------------------------------------------------------------------- 1 | jacob.dll 2 | jacob.lib 3 | jacob.exp 4 | 5 | -------------------------------------------------------------------------------- /src/jni/ComThread.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #include "stdafx.h" 21 | #include 22 | #include "ComThread.h" 23 | // Win32 support for Ole Automation 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "util.h" 30 | 31 | extern "C" 32 | { 33 | 34 | JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoInitialize 35 | (JNIEnv *env, jclass cls, jint mode) 36 | { 37 | int threadModel = mode; 38 | CoInitializeEx(NULL, threadModel); 39 | } 40 | 41 | JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoUninitialize 42 | (JNIEnv *env, jclass cls) 43 | { 44 | CoUninitialize(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/jni/ComThread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #include 21 | /* Header for class com_jacob_com_ComThread */ 22 | 23 | #ifndef _Included_com_jacob_com_ComThread 24 | #define _Included_com_jacob_com_ComThread 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | /* 29 | * Class: com_jacob_com_ComThread 30 | * Method: doCoInitialize 31 | * Signature: (I)V 32 | */ 33 | JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoInitialize 34 | (JNIEnv *, jclass, jint); 35 | 36 | /* 37 | * Class: com_jacob_com_ComThread 38 | * Method: doCoUninitialize 39 | * Signature: ()V 40 | */ 41 | JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoUninitialize 42 | (JNIEnv *, jclass); 43 | 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | #endif 49 | -------------------------------------------------------------------------------- /src/jni/Dispatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #include 21 | /* Header for class Dispatch */ 22 | 23 | #ifndef _Included_Dispatch 24 | #define _Included_Dispatch 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | /* 29 | * Class: com_jacob_com_Dispatch 30 | * Method: QueryInterface 31 | * Signature: (Ljava/lang/String;)Lcom/jacob/com/Dispatch; 32 | */ 33 | JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_QueryInterface 34 | (JNIEnv *, jobject, jstring); 35 | 36 | /* 37 | * Class: Dispatch 38 | * Method: createInstance 39 | * Signature: (Ljava/lang/String;)V 40 | */ 41 | JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstanceNative 42 | (JNIEnv *, jobject, jstring); 43 | 44 | /* 45 | * Class: Dispatch 46 | * Method: getActiveInstance 47 | * Signature: (Ljava/lang/String;)V 48 | */ 49 | JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_getActiveInstanceNative 50 | (JNIEnv *, jobject, jstring); 51 | 52 | /* 53 | * Class: Dispatch 54 | * Method: coCreateInstance 55 | * Signature: (Ljava/lang/String;)V 56 | */ 57 | JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_coCreateInstanceNative 58 | (JNIEnv *, jobject, jstring); 59 | 60 | /* 61 | * Class: Dispatch 62 | * Method: release 63 | * Signature: ()V 64 | */ 65 | JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_release 66 | (JNIEnv *, jobject); 67 | 68 | /* 69 | * Class: Dispatch 70 | * Method: getIDsOfNames 71 | * Signature: (Ljava/lang/Object;I[Ljava/lang/String;)[I 72 | */ 73 | JNIEXPORT jintArray JNICALL Java_com_jacob_com_Dispatch_getIDsOfNames 74 | (JNIEnv *, jclass, jobject, jint, jobjectArray); 75 | 76 | /* 77 | * Class: Dispatch 78 | * Method: invokev 79 | * Signature: (Ljava/lang/Object;Ljava/lang/String;III[LVariant;[I)LVariant; 80 | */ 81 | JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev 82 | (JNIEnv *, jclass, jobject, jstring, jint, jint, jint, jobjectArray, jintArray); 83 | 84 | /* 85 | * Class: Dispatch 86 | * Method: wait 87 | * Signature: (Ljava/lang/Object;I;)I 88 | */ 89 | JNIEXPORT jint JNICALL Java_com_jacob_com_Dispatch_hasExited 90 | (JNIEnv *, jclass, jobject, jint, jint); 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | #endif 96 | -------------------------------------------------------------------------------- /src/jni/DispatchEvents.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #include 21 | /* Header for class DispatchEvents */ 22 | 23 | #ifndef _Included_DispatchEvents 24 | #define _Included_DispatchEvents 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* 30 | * Class: com_jacob_com_DispatchEvents 31 | * Method: init3 32 | * Signature: (Lcom/jacob/com/Dispatch;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V 33 | */ 34 | JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init3 35 | (JNIEnv *, jobject, jobject, jobject, jstring, jstring); 36 | 37 | /* 38 | * Class: DispatchEvents 39 | * Method: release 40 | * Signature: ()V 41 | */ 42 | JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_release 43 | (JNIEnv *, jobject); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | #endif 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/jni/DispatchProxy.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #include "stdafx.h" 21 | #include 22 | #include "ComThread.h" 23 | // Win32 support for Ole Automation 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "util.h" 30 | 31 | extern "C" 32 | { 33 | 34 | // extract a IStream from a jobject 35 | IStream *extractStream(JNIEnv *env, jobject arg) 36 | { 37 | jclass argClass = env->GetObjectClass(arg); 38 | jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "J"); 39 | jlong anum = env->GetLongField(arg, ajf); 40 | IStream *v = (IStream *)anum; 41 | return v; 42 | } 43 | 44 | JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_MarshalIntoStream 45 | (JNIEnv *env, jobject _this, jobject disp) 46 | { 47 | IDispatch *pIDispatch = extractDispatch(env, disp); 48 | if (!pIDispatch) return; 49 | IStream *ps; // this is the stream we will marshall into 50 | HRESULT hr = CoMarshalInterThreadInterfaceInStream( 51 | IID_IDispatch, pIDispatch, &ps); 52 | if (!SUCCEEDED(hr)) 53 | { 54 | ThrowComFail(env, "Could not Marshal Dispatch into IStream", hr); 55 | return; 56 | } 57 | // store the stream pointer on the object 58 | jclass argClass = env->GetObjectClass(_this); 59 | jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "J"); 60 | env->SetLongField(_this, ajf, (jlong)ps); 61 | } 62 | 63 | JNIEXPORT jobject JNICALL Java_com_jacob_com_DispatchProxy_MarshalFromStream 64 | (JNIEnv *env, jobject _this) 65 | { 66 | IStream *ps = extractStream(env, _this); 67 | if (!ps) 68 | { 69 | ThrowComFail(env, "Could not get IStream from DispatchProxy", -1); 70 | return NULL; 71 | } 72 | IDispatch *pD; 73 | HRESULT hr = CoGetInterfaceAndReleaseStream(ps, IID_IDispatch, (void **)&pD); 74 | // zero out the stream pointer on the object 75 | // since the stream can only be read once 76 | jclass argClass = env->GetObjectClass(_this); 77 | jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "J"); 78 | env->SetLongField(_this, ajf, 0ll); 79 | 80 | if (!SUCCEEDED(hr)) 81 | { 82 | ThrowComFail(env, "Could not Marshal Dispatch from IStream", hr); 83 | return NULL; 84 | } 85 | jclass autoClass = env->FindClass("com/jacob/com/Dispatch"); 86 | jmethodID autoCons = env->GetMethodID(autoClass, "", "(J)V"); 87 | // construct a Dispatch object to return 88 | // I am copying the pointer to java 89 | if (pD) pD->AddRef(); 90 | // jacobproject/bug/132 91 | jobject newAuto = env->NewObject(autoClass, autoCons, (jlong)(uintptr_t)pD); 92 | return newAuto; 93 | } 94 | 95 | JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_release 96 | (JNIEnv *env, jobject _this) 97 | { 98 | IStream *ps = extractStream(env, _this); 99 | if (ps) { 100 | ps->Release(); 101 | jclass argClass = env->GetObjectClass(_this); 102 | jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "J"); 103 | env->SetLongField(_this, ajf, 0ll); 104 | } 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/jni/DispatchProxy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #include 21 | /* Header for class com_jacob_com_DispatchProxy */ 22 | 23 | #ifndef _Included_com_jacob_com_DispatchProxy 24 | #define _Included_com_jacob_com_DispatchProxy 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | /* 29 | * Class: com_jacob_com_DispatchProxy 30 | * Method: MarshalIntoStream 31 | * Signature: (Lcom/jacob/com/Dispatch;)V 32 | */ 33 | JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_MarshalIntoStream 34 | (JNIEnv *, jobject, jobject); 35 | 36 | /* 37 | * Class: com_jacob_com_DispatchProxy 38 | * Method: MarshalFromStream 39 | * Signature: ()Lcom/jacob/com/Dispatch; 40 | */ 41 | JNIEXPORT jobject JNICALL Java_com_jacob_com_DispatchProxy_MarshalFromStream 42 | (JNIEnv *, jobject); 43 | 44 | /* 45 | * Class: com_jacob_com_DispatchProxy 46 | * Method: release 47 | * Signature: ()V 48 | */ 49 | JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_release 50 | (JNIEnv *, jobject); 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | #endif 56 | -------------------------------------------------------------------------------- /src/jni/EnumVariant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #ifndef _Included_EnumVariant 21 | #define _Included_EnumVariant 22 | 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | /* 29 | * Class: com_jacob_com_EnumVariant 30 | * Method: Next 31 | * Signature: ([Lcom/jacob/com/Variant;)I 32 | */ 33 | JNIEXPORT jint JNICALL Java_com_jacob_com_EnumVariant_Next 34 | (JNIEnv *, jobject, jobjectArray); 35 | 36 | /* 37 | * Class: com_jacob_com_EnumVariant 38 | * Method: Release 39 | * Signature: ()V 40 | */ 41 | JNIEXPORT void JNICALL Java_com_jacob_com_EnumVariant_release 42 | (JNIEnv *, jobject); 43 | 44 | /* 45 | * Class: com_jacob_com_EnumVariant 46 | * Method: Reset 47 | * Signature: ()V 48 | */ 49 | JNIEXPORT void JNICALL Java_com_jacob_com_EnumVariant_Reset 50 | (JNIEnv *, jobject); 51 | 52 | /* 53 | * Class: com_jacob_com_EnumVariant 54 | * Method: Skip 55 | * Signature: (I)V 56 | */ 57 | JNIEXPORT void JNICALL Java_com_jacob_com_EnumVariant_Skip 58 | (JNIEnv *, jobject, jint); 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | #endif 64 | -------------------------------------------------------------------------------- /src/jni/EventProxy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "stdafx.h" 25 | #include "util.h" 26 | 27 | /* 28 | * An instance of this class stands between a connection point 29 | * and a java object. When it gets invoked from the cp, it reflects 30 | * the call into the java object dynamically. The eventIID is passed 31 | * in as are the valid dispids and the corresponding names. A map 32 | * is created between the dispids and the java object's method in 33 | * the constructor. For now, all the java event methods have to have 34 | * the same signature: (Variant[]) 35 | */ 36 | class EventProxy : public IDispatch 37 | { 38 | private: 39 | int connected; 40 | LONG m_cRef; // a reference counter 41 | CComPtr pCP; // the connection point 42 | DWORD dwEventCookie; // connection point cookie 43 | jobject javaSinkObj; // the java object to delegate calls 44 | 45 | IID eventIID; // the interface iid passed in 46 | int MethNum; // number of methods in the callback interface 47 | CComBSTR *MethName; // Array of method names 48 | DISPID *MethID; // Array of method ids, used to match invokations to method names 49 | JavaVM *jvm; // The java vm we are running 50 | void convertJavaVariant(VARIANT *java, VARIANT *com); 51 | void Connect(JNIEnv *env); 52 | public: 53 | // constuct with a global JNI ref to a sink object 54 | // to which we will delegate event callbacks 55 | EventProxy(JNIEnv *jenv, 56 | jobject aSinkObj, 57 | CComPtr pConn, 58 | IID eventIID, 59 | CComBSTR *mName, 60 | DISPID *mID, 61 | int mNum); 62 | ~EventProxy(); 63 | 64 | // IUnknown methods 65 | STDMETHODIMP_(ULONG) AddRef(void) 66 | { 67 | LONG res = InterlockedIncrement(&m_cRef); 68 | return res; 69 | } 70 | 71 | STDMETHODIMP_(ULONG) Release(void) 72 | { 73 | LONG res = InterlockedDecrement(&m_cRef); 74 | if (res == 0) { 75 | delete this; 76 | } 77 | return res; 78 | 79 | } 80 | 81 | STDMETHODIMP QueryInterface(REFIID rid, void **ppv); 82 | 83 | // IDispatch methods 84 | STDMETHODIMP GetTypeInfoCount(UINT *num) 85 | { 86 | *num = 0; 87 | return S_OK; 88 | } 89 | 90 | STDMETHODIMP GetTypeInfo(UINT, LCID, ITypeInfo **pptInfo) 91 | { 92 | *pptInfo=NULL; 93 | return E_NOTIMPL; 94 | } 95 | 96 | // These are the actual supported methods 97 | STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR **, UINT, LCID , DISPID *); 98 | STDMETHODIMP Invoke(DISPID, REFIID, LCID, WORD , DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *); 99 | // SF 3412922 make public to support cleanup from DispatchEvents 100 | void Disconnect(); 101 | 102 | }; 103 | -------------------------------------------------------------------------------- /src/jni/STA.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #include "stdafx.h" 21 | #include 22 | #include "ComThread.h" 23 | // Win32 support for Ole Automation 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "util.h" 30 | 31 | extern "C" 32 | { 33 | 34 | JNIEXPORT void JNICALL Java_com_jacob_com_STA_doMessagePump 35 | (JNIEnv *env, jobject obj) 36 | { 37 | // store the current thread id so we can kill it 38 | jclass argClass = env->GetObjectClass(obj); 39 | jfieldID ajf = env->GetFieldID( argClass, "threadID", "I"); 40 | jint threadID = (jint)GetCurrentThreadId(); 41 | env->SetIntField(obj, ajf, threadID); 42 | 43 | MSG msg; 44 | 45 | ZeroMemory(&msg, sizeof(msg)); 46 | msg.wParam = S_OK; 47 | 48 | while (GetMessage(&msg, NULL, 0, 0)) 49 | { 50 | DispatchMessage(&msg); 51 | } 52 | } 53 | 54 | JNIEXPORT void JNICALL Java_com_jacob_com_STA_quitMessagePump 55 | (JNIEnv *env, jobject obj) 56 | { 57 | jclass argClass = env->GetObjectClass(obj); 58 | jfieldID ajf = env->GetFieldID( argClass, "threadID", "I"); 59 | jint threadID = env->GetIntField(obj, ajf); 60 | PostThreadMessage((DWORD)threadID, WM_QUIT, 0, 0); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/jni/STA.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #include 21 | /* Header for class STA */ 22 | 23 | #ifndef _Included_com_jacob_com_STA 24 | #define _Included_com_jacob_com_STA 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | /* 29 | * Class: com_jacob_com_STA 30 | * Method: doMessagePump 31 | * Signature: ()V 32 | */ 33 | JNIEXPORT void JNICALL Java_com_jacob_com_STA_doMessagePump 34 | (JNIEnv *, jobject); 35 | 36 | /* 37 | * Class: com_jacob_com_STA 38 | * Method: quitMessagePump 39 | * Signature: ()V 40 | */ 41 | JNIEXPORT void JNICALL Java_com_jacob_com_STA_quitMessagePump 42 | (JNIEnv *, jobject); 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | #endif 48 | -------------------------------------------------------------------------------- /src/jni/StdAfx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | // stdafx.h : include file for standard system include files, 21 | // or project specific include files that are used frequently, 22 | // but are changed infrequently 23 | 24 | #if !defined(AFX_STDAFX_H__9988E984_6789_11D3_A646_000000000000__INCLUDED_) 25 | #define AFX_STDAFX_H__9988E984_6789_11D3_A646_000000000000__INCLUDED_ 26 | 27 | #if _MSC_VER > 1000 28 | #pragma once 29 | #endif // _MSC_VER > 1000 30 | 31 | #ifndef STRICT 32 | #define STRICT 33 | #endif 34 | // SF 3377279 Changed _WIN32_WINNT to 0x0500 to fix build with VS2010 35 | // 0x400 is NT or later 0x500 is windows 2000 or later. we could go higher 36 | #ifndef _WIN32_WINNT 37 | #define _WIN32_WINNT 0x0500 38 | #endif 39 | //#define _ATL_APARTMENT_THREADED 40 | #include 41 | #include 42 | #include 43 | //You may derive a class from CComModule and use it if you want to override 44 | //something, but do not change the name of _Module 45 | extern CComModule _Module; 46 | //#include 47 | 48 | 49 | //{{AFX_INSERT_LOCATION}} 50 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line. 51 | 52 | #endif // !defined(AFX_STDAFX_H__9988E984_6789_11D3_A646_000000000000__INCLUDED) 53 | -------------------------------------------------------------------------------- /src/jni/util.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #include "Dispatch.h" 21 | // Win32 support for Ole Automation 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "util.h" 29 | 30 | extern "C" 31 | { 32 | 33 | void ThrowComFail(JNIEnv *env, const char* desc, jint hr) 34 | { 35 | jclass failClass = env->FindClass("com/jacob/com/ComFailException"); 36 | // call the constructor that takes hr and message 37 | jmethodID failCons = 38 | env->GetMethodID(failClass, "", "(ILjava/lang/String;)V"); 39 | if (!desc) { 40 | desc = "Java/COM Error"; 41 | } 42 | jstring js = env->NewStringUTF(desc); 43 | jthrowable fail = (jthrowable)env->NewObject(failClass, failCons, hr, js); 44 | env->Throw(fail); 45 | } 46 | 47 | void ThrowComFailUnicode(JNIEnv *env, const wchar_t* desc, jint hr) 48 | { 49 | if (!desc) { 50 | ThrowComFail(env, "Java/COM Error", hr); 51 | } 52 | jclass failClass = env->FindClass("com/jacob/com/ComFailException"); 53 | // call the constructor that takes hr and message 54 | jmethodID failCons = 55 | env->GetMethodID(failClass, "", "(ILjava/lang/String;)V"); 56 | jstring js = env->NewString((const jchar *) desc, wcslen(desc)); 57 | jthrowable fail = (jthrowable)env->NewObject(failClass, failCons, hr, js); 58 | env->Throw(fail); 59 | } 60 | 61 | // if env's are different throw on the 1st env 62 | int CheckEnv(JNIEnv *env1, JNIEnv *env2) 63 | { 64 | if (env1 != env2) { 65 | jclass failClass = env1->FindClass("com/jacob/com/WrongThreadException"); 66 | // call the constructor that takes hr and message 67 | jmethodID failCons = 68 | env1->GetMethodID(failClass, "", "()V"); 69 | env1->ThrowNew(failClass, "Wrong Thread"); 70 | return 0; 71 | } 72 | return 1; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/jni/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #include 21 | extern "C" { 22 | VARIANT *extractVariant(JNIEnv *env, jobject arg); 23 | void ThrowComFail(JNIEnv *env, const char* desc, jint hr); 24 | void ThrowComFailUnicode(JNIEnv *env, const wchar_t* desc, jint hr); 25 | IDispatch *extractDispatch(JNIEnv *env, jobject arg); 26 | SAFEARRAY *extractSA(JNIEnv *env, jobject arg); 27 | void setSA(JNIEnv *env, jobject arg, SAFEARRAY *sa, int copy); 28 | SAFEARRAY *copySA(SAFEARRAY *psa); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/com/jacob/activeX/ActiveXDispatchEvents.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.activeX; 21 | 22 | import com.jacob.com.Dispatch; 23 | import com.jacob.com.DispatchEvents; 24 | import com.jacob.com.InvocationProxy; 25 | 26 | /** 27 | * RELEASE 1.12 EXPERIMENTAL. 28 | *

29 | * Use this exactly like the DispatchEvents class. This class plugs in an 30 | * ActiveXInvocationProxy instead of an InvocationProxy. It is the 31 | * ActiveXInvocationProxy that implements the reflection calls and invoke the 32 | * found java event callbacks. See ActiveXInvocationProxy for details. 33 | * 34 | * 35 | */ 36 | public class ActiveXDispatchEvents extends DispatchEvents { 37 | 38 | /** 39 | * This is the most commonly used constructor. 40 | *

41 | * Creates the event callback linkage between the the MS program represented 42 | * by the Dispatch object and the Java object that will receive the 43 | * callback. 44 | * 45 | * @param sourceOfEvent Dispatch object who's MS app will generate callbacks 46 | * @param eventSink Java object that wants to receive the events 47 | */ 48 | public ActiveXDispatchEvents(Dispatch sourceOfEvent, Object eventSink) { 49 | super(sourceOfEvent, eventSink, null); 50 | } 51 | 52 | /** 53 | * None of the samples use this constructor. 54 | *

55 | * Creates the event callback linkage between the the MS program represented 56 | * by the Dispatch object and the Java object that will receive the 57 | * callback. 58 | * 59 | * @param sourceOfEvent 60 | * Dispatch object who's MS app will generate callbacks 61 | * @param eventSink 62 | * Java object that wants to receive the events 63 | * @param progId 64 | * ??? 65 | */ 66 | public ActiveXDispatchEvents(Dispatch sourceOfEvent, Object eventSink, 67 | String progId) { 68 | super(sourceOfEvent, eventSink, progId, null); 69 | } 70 | 71 | /** 72 | * Creates the event callback linkage between the the MS program represented 73 | * by the Dispatch object and the Java object that will receive the 74 | * callback. 75 | * 76 | *

 77 | 	 * ActiveXDispatchEvents de = new ActiveXDispatchEvents(someDispatch, someEventHAndler,
 78 | 	 * 		"Excel.Application",
 79 | 	 * 		"C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE");
 80 | 	 * 
81 | * 82 | * @param sourceOfEvent Dispatch object who's MS app will generate callbacks 83 | * @param eventSink Java object that wants to receive the events 84 | * @param progId , mandatory if the typelib is specified 85 | * @param typeLib The location of the typelib to use 86 | * 87 | */ 88 | public ActiveXDispatchEvents(Dispatch sourceOfEvent, Object eventSink, 89 | String progId, String typeLib) { 90 | super(sourceOfEvent, eventSink, progId, typeLib); 91 | } 92 | 93 | /* 94 | * (non-Javadoc) 95 | * 96 | * @see com.jacob.com.DispatchEvents#getInvocationProxy(java.lang.Object) 97 | */ 98 | protected InvocationProxy getInvocationProxy(Object pTargetObject) { 99 | InvocationProxy newProxy = new ActiveXInvocationProxy(); 100 | newProxy.setTarget(pTargetObject); 101 | return newProxy; 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/main/com/jacob/com/ComException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | /** 23 | * Standard exception thrown by com jni code when there is a problem 24 | */ 25 | public abstract class ComException extends JacobException { 26 | 27 | /** 28 | * COM code initializes this filed with an appropriate return code that was 29 | * returned by the underlying com code 30 | */ 31 | protected int hr; 32 | /** 33 | * No documentation is available at this time. Someone should document this 34 | * field 35 | */ 36 | protected int m_helpContext; 37 | /** 38 | * No documentation is available at this time. Someone should document this 39 | * field 40 | */ 41 | protected String m_helpFile; 42 | /** 43 | * No documentation is available at this time. Someone should document this 44 | * field 45 | */ 46 | protected String m_source; 47 | 48 | /** 49 | * constructor 50 | * 51 | */ 52 | public ComException() { 53 | super(); 54 | } 55 | 56 | /** 57 | * constructor with error code? 58 | * 59 | * @param newHr ?? 60 | */ 61 | public ComException(int newHr) { 62 | super(); 63 | this.hr = newHr; 64 | } 65 | 66 | /** 67 | * @param newHr 68 | * @param description 69 | */ 70 | public ComException(int newHr, String description) { 71 | super(description); 72 | this.hr = newHr; 73 | } 74 | 75 | /** 76 | * @param newHr 77 | * @param source 78 | * @param helpFile 79 | * @param helpContext 80 | */ 81 | public ComException(int newHr, String source, String helpFile, 82 | int helpContext) { 83 | super(); 84 | this.hr = newHr; 85 | m_source = source; 86 | m_helpFile = helpFile; 87 | m_helpContext = helpContext; 88 | } 89 | 90 | /** 91 | * @param newHr 92 | * @param description 93 | * @param source 94 | * @param helpFile 95 | * @param helpContext 96 | */ 97 | public ComException(int newHr, String description, String source, 98 | String helpFile, int helpContext) { 99 | super(description); 100 | this.hr = newHr; 101 | m_source = source; 102 | m_helpFile = helpFile; 103 | m_helpContext = helpContext; 104 | } 105 | 106 | /** 107 | * @param description 108 | */ 109 | public ComException(String description) { 110 | super(description); 111 | } 112 | 113 | /** 114 | * @return int representation of the help context 115 | */ 116 | // Methods 117 | public int getHelpContext() { 118 | return m_helpContext; 119 | } 120 | 121 | /** 122 | * @return String ??? help file 123 | */ 124 | public String getHelpFile() { 125 | return m_helpFile; 126 | } 127 | 128 | /** 129 | * @return int hr result ?? 130 | */ 131 | public int getHResult() { 132 | return hr; 133 | } 134 | 135 | /** 136 | * @return String source ?? 137 | */ 138 | public String getSource() { 139 | return m_source; 140 | } 141 | } -------------------------------------------------------------------------------- /src/main/com/jacob/com/ComFailException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | /** 23 | * COM Fail Exception class raised when there is a problem 24 | */ 25 | public class ComFailException extends ComException { 26 | /** 27 | * eclipse generated to get rid of a wanring 28 | */ 29 | private static final long serialVersionUID = -266047261992987700L; 30 | 31 | /** 32 | * Constructor 33 | * 34 | * @param hrNew 35 | */ 36 | public ComFailException(int hrNew) { 37 | super(hrNew); 38 | } 39 | 40 | /** 41 | * Constructor 42 | * 43 | * @param hrNew 44 | * @param message 45 | */ 46 | public ComFailException(int hrNew, String message) { 47 | super(hrNew, message); 48 | } 49 | 50 | /** 51 | * @param hrNew 52 | * @param source 53 | * @param helpFile 54 | * @param helpContext 55 | */ 56 | public ComFailException(int hrNew, String source, String helpFile, 57 | int helpContext) { 58 | super(hrNew, source, helpFile, helpContext); 59 | } 60 | 61 | /** 62 | * Constructor 63 | * 64 | * @param hrNew 65 | * @param description 66 | * @param source 67 | * @param helpFile 68 | * @param helpContext 69 | */ 70 | public ComFailException(int hrNew, String description, String source, 71 | String helpFile, int helpContext) { 72 | super(hrNew, description, source, helpFile, helpContext); 73 | } 74 | 75 | /** 76 | * No argument Constructor 77 | */ 78 | public ComFailException() { 79 | super(); 80 | } 81 | 82 | /** 83 | * @param message 84 | */ 85 | public ComFailException(String message) { 86 | super(message); 87 | } 88 | } -------------------------------------------------------------------------------- /src/main/com/jacob/com/Currency.java: -------------------------------------------------------------------------------- 1 | package com.jacob.com; 2 | 3 | /** 4 | * Most COM bridges use java.lang.Long as their Java data type for COM Currency 5 | * data. This is because COM currency is a 64 bit number where the last 4 digits 6 | * represent the milli-cents. We wanted to support 64 bit Long values for x64 7 | * platforms so that meant we wanted to map Java.LONG to COM.LONG even though it 8 | * only works for 64 bit platforms. The end result was we needed a new 9 | * representation for Money so we have this. 10 | *

11 | * In the future, this should convert to and from BigDecimal or Double 12 | */ 13 | 14 | public class Currency 15 | // Added EJP 31/8/2023 16 | implements Comparable { 17 | Long embeddedValue = null; 18 | 19 | /** 20 | * constructor that takes a long already in COM representation 21 | * 22 | * @param newValue New value. 23 | */ 24 | public Currency(long newValue) { 25 | embeddedValue = new Long(newValue); 26 | } 27 | 28 | /** 29 | * constructor that takes a String already in COM representation 30 | * 31 | * @param newValue New value. 32 | */ 33 | public Currency(String newValue) { 34 | embeddedValue = new Long(newValue); 35 | } 36 | 37 | /** 38 | * Return the currency as a primitive long. 39 | * 40 | * @return the currency as a primitive long 41 | */ 42 | public long longValue() { 43 | return embeddedValue.longValue(); 44 | } 45 | 46 | /** 47 | * Getter to the inner Long so that {@link Comparable#compareTo} can work 48 | * 49 | * @return the embedded Long value 50 | */ 51 | protected Long getLongValue() { 52 | return embeddedValue; 53 | } 54 | 55 | /** 56 | * Compares the values of two currencies 57 | * 58 | * @param anotherCurrency Currency object to compare to. 59 | * @return the usual compareTo results 60 | */ 61 | @Override 62 | public int compareTo(Currency anotherCurrency) { 63 | return embeddedValue.compareTo(anotherCurrency.getLongValue()); 64 | } 65 | 66 | // /** 67 | // * standard comparison 68 | // * 69 | // * @param o 70 | // * must be Currency or Long 71 | // * @return the usual compareTo results 72 | // * Deleted EJP 31/8/2023 when I added 'implements Comparable. 73 | // * The compiler will still generate this method as a bridge method. 74 | // */ 75 | // public int compareTo(Object o) { 76 | // if (o instanceof Currency) { 77 | // return compareTo((Currency) o); 78 | // } else if (o instanceof Long) { 79 | // return embeddedValue.compareTo((Long) o); 80 | // } else 81 | // throw new IllegalArgumentException( 82 | // "Can only compare to Long and Currency not " 83 | // + o.getClass().getName()); 84 | // } 85 | 86 | /* 87 | * {@inheritDoc} 88 | */ 89 | @Override 90 | public boolean equals(Object o) { 91 | if (o == null) { 92 | return false; 93 | // Modified EJP 31/8/2023 94 | } else if (o instanceof Currency && compareTo((Currency) o) == 0) { 95 | return true; 96 | } else { 97 | return false; 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /src/main/com/jacob/com/DateUtilities.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | import java.util.Calendar; 23 | import java.util.Date; 24 | 25 | /** 26 | * java / windows date conversion utilities 27 | * 28 | * @author joe 29 | * 30 | */ 31 | public class DateUtilities { 32 | 33 | /** 34 | * converts a windows time to a Java Date Object 35 | * 36 | * @param comTime time in windows format 37 | * @return Date object representing the windows time as specified in comTime 38 | */ 39 | static public Date convertWindowsTimeToDate(double comTime) { 40 | return new Date(convertWindowsTimeToMilliseconds(comTime)); 41 | } 42 | 43 | /** 44 | * Convert a COM time from functions Date(), Time(), Now() to a Java time 45 | * (milliseconds). Visual Basic time values are based to 30.12.1899, Java 46 | * time values are based to 1.1.1970 (= 0 milliseconds). The difference is 47 | * added to the Visual Basic value to get the corresponding Java value. The 48 | * Visual Basic double value reads: <day count delta since 30.12.1899>. 49 | * <1 day percentage fraction >, e.g. "38100.6453" means: 38100 days since 50 | * 30.12.1899 plus (24 hours * 0.6453). Example usage: 51 | * Date javaDate = new Date(toMilliseconds (vbDate));. 52 | * 53 | * @param comTime COM time. 54 | * @return Java time. 55 | */ 56 | static public long convertWindowsTimeToMilliseconds(double comTime) { 57 | long result = 0; 58 | 59 | // code from jacobgen: 60 | comTime = comTime - 25569D; 61 | Calendar cal = Calendar.getInstance(); 62 | result = Math.round(86400000L * comTime) 63 | - cal.get(Calendar.ZONE_OFFSET); 64 | cal.setTime(new Date(result)); 65 | result -= cal.get(Calendar.DST_OFFSET); 66 | 67 | return result; 68 | }// convertWindowsTimeToMilliseconds() 69 | 70 | /** 71 | * converts a java date to a windows time object (is this timezone safe?) 72 | * 73 | * @param javaDate 74 | * the java date to be converted to windows time 75 | * @return the double representing the date in a form windows understands 76 | */ 77 | static public double convertDateToWindowsTime(Date javaDate) { 78 | if (javaDate == null) { 79 | throw new IllegalArgumentException( 80 | "cannot convert null to windows time"); 81 | } 82 | return convertMillisecondsToWindowsTime(javaDate.getTime()); 83 | } 84 | 85 | /** 86 | * Convert a Java time to a COM time. 87 | * 88 | * @param milliseconds Java time. 89 | * @return COM time. 90 | */ 91 | static public double convertMillisecondsToWindowsTime(long milliseconds) { 92 | double result = 0.0; 93 | 94 | // code from jacobgen: 95 | Calendar cal = Calendar.getInstance(); 96 | cal.setTimeInMillis(milliseconds); 97 | milliseconds += (cal.get(Calendar.ZONE_OFFSET) + cal 98 | .get(Calendar.DST_OFFSET)); // add GMT offset 99 | result = (milliseconds / 86400000D) + 25569D; 100 | 101 | return result; 102 | }// convertMillisecondsToWindowsTime() 103 | } 104 | -------------------------------------------------------------------------------- /src/main/com/jacob/com/DispatchIdentifier.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.jacob.com; 5 | 6 | /** 7 | * A bunch of DispatchIds that were pulled out of the Dispatch class for version 8 | * 1.14. 9 | */ 10 | public class DispatchIdentifier { 11 | 12 | private DispatchIdentifier() { 13 | // This is utility class so there is no constructor. 14 | } 15 | 16 | public static final int DISPID_UNKNOWN = -1; 17 | public static final int DISPID_VALUE = 0; 18 | public static final int DISPID_PROPERTYPUT = -3; 19 | public static final int DISPID_NEWENUM = -4; 20 | public static final int DISPID_EVALUATE = -5; 21 | public static final int DISPID_CONSTRUCTOR = -6; 22 | public static final int DISPID_DESTRUCTOR = -7; 23 | public static final int DISPID_COLLECT = -8; 24 | public static final int DISPID_AUTOSIZE = -500; 25 | public static final int DISPID_BACKCOLOR = -501; 26 | public static final int DISPID_BACKSTYLE = -502; 27 | public static final int DISPID_BORDERCOLOR = -503; 28 | public static final int DISPID_BORDERSTYLE = -504; 29 | public static final int DISPID_BORDERWIDTH = -505; 30 | public static final int DISPID_DRAWMODE = -507; 31 | public static final int DISPID_DRAWSTYLE = -508; 32 | public static final int DISPID_DRAWWIDTH = -509; 33 | public static final int DISPID_FILLCOLOR = -510; 34 | public static final int DISPID_FILLSTYLE = -511; 35 | public static final int DISPID_FONT = -512; 36 | public static final int DISPID_FORECOLOR = -513; 37 | public static final int DISPID_ENABLED = -514; 38 | public static final int DISPID_HWND = -515; 39 | public static final int DISPID_TABSTOP = -516; 40 | public static final int DISPID_TEXT = -517; 41 | public static final int DISPID_CAPTION = -518; 42 | public static final int DISPID_BORDERVISIBLE = -519; 43 | public static final int DISPID_APPEARANCE = -520; 44 | public static final int DISPID_MOUSEPOINTER = -521; 45 | public static final int DISPID_MOUSEICON = -522; 46 | public static final int DISPID_PICTURE = -523; 47 | public static final int DISPID_VALID = -524; 48 | public static final int DISPID_READYSTATE = -525; 49 | public static final int DISPID_REFRESH = -550; 50 | public static final int DISPID_DOCLICK = -551; 51 | public static final int DISPID_ABOUTBOX = -552; 52 | public static final int DISPID_CLICK = -600; 53 | public static final int DISPID_DBLCLICK = -601; 54 | public static final int DISPID_KEYDOWN = -602; 55 | public static final int DISPID_KEYPRESS = -603; 56 | public static final int DISPID_KEYUP = -604; 57 | public static final int DISPID_MOUSEDOWN = -605; 58 | public static final int DISPID_MOUSEMOVE = -606; 59 | public static final int DISPID_MOUSEUP = -607; 60 | public static final int DISPID_ERROREVENT = -608; 61 | public static final int DISPID_READYSTATECHANGE = -609; 62 | public static final int DISPID_AMBIENT_BACKCOLOR = -701; 63 | public static final int DISPID_AMBIENT_DISPLAYNAME = -702; 64 | public static final int DISPID_AMBIENT_FONT = -703; 65 | public static final int DISPID_AMBIENT_FORECOLOR = -704; 66 | public static final int DISPID_AMBIENT_LOCALEID = -705; 67 | public static final int DISPID_AMBIENT_MESSAGEREFLECT = -706; 68 | public static final int DISPID_AMBIENT_SCALEUNITS = -707; 69 | public static final int DISPID_AMBIENT_TEXTALIGN = -708; 70 | public static final int DISPID_AMBIENT_USERMODE = -709; 71 | public static final int DISPID_AMBIENT_UIDEAD = -710; 72 | public static final int DISPID_AMBIENT_SHOWGRABHANDLES = -711; 73 | public static final int DISPID_AMBIENT_SHOWHATCHING = -712; 74 | public static final int DISPID_AMBIENT_DISPLAYASDEFAULT = -713; 75 | public static final int DISPID_AMBIENT_SUPPORTSMNEMONICS = -714; 76 | public static final int DISPID_AMBIENT_AUTOCLIP = -715; 77 | public static final int DISPID_AMBIENT_APPEARANCE = -716; 78 | public static final int DISPID_AMBIENT_CODEPAGE = -725; 79 | public static final int DISPID_AMBIENT_PALETTE = -726; 80 | public static final int DISPID_AMBIENT_CHARSET = -727; 81 | public static final int DISPID_AMBIENT_TRANSFERPRIORITY = -728; 82 | } 83 | -------------------------------------------------------------------------------- /src/main/com/jacob/com/DispatchProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | /** 23 | * If you need to pass a COM Dispatch object between STA threads, you have to 24 | * marshall the interface. This class is used as follows: the STA that creates 25 | * the Dispatch object must construct an instance of this class. Another thread 26 | * can then call toDispatch() on that instance and get a Dispatch pointer which 27 | * has been marshalled. WARNING: You can only call toDispatch() once! If you 28 | * need to call it multiple times (or from multiple threads) you need to 29 | * construct a separate DispatchProxy instance for each such case! 30 | */ 31 | public class DispatchProxy extends JacobObject { 32 | /** 33 | * Comment for m_pStream 34 | */ 35 | public long m_pStream; 36 | 37 | /** 38 | * Marshals the passed in dispatch into the stream 39 | * 40 | * @param localDispatch 41 | */ 42 | public DispatchProxy(Dispatch localDispatch) { 43 | MarshalIntoStream(localDispatch); 44 | } 45 | 46 | /** 47 | * 48 | * @return Dispatch the dispatch retrieved from the stream 49 | */ 50 | public Dispatch toDispatch() { 51 | return MarshalFromStream(); 52 | } 53 | 54 | private native void MarshalIntoStream(Dispatch d); 55 | 56 | private native Dispatch MarshalFromStream(); 57 | 58 | /** 59 | * now private so only this object can access was: call this to explicitly 60 | * release the com object before gc 61 | * 62 | */ 63 | private native void release(); 64 | 65 | /* 66 | * (non-Javadoc) 67 | * 68 | * @see java.lang.Object#finalize() 69 | */ 70 | @Override 71 | public void finalize() { 72 | safeRelease(); 73 | } 74 | 75 | /* 76 | * (non-Javadoc) 77 | * 78 | * @see com.jacob.com.JacobObject#safeRelease() 79 | */ 80 | @Override 81 | public void safeRelease() { 82 | super.safeRelease(); 83 | if (m_pStream != 0) { 84 | release(); 85 | m_pStream = 0; 86 | } else { 87 | // looks like a double release 88 | if (isDebugEnabled()) { 89 | debug(this.getClass().getName() + ":" + this.hashCode() 90 | + " double release"); 91 | } 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /src/main/com/jacob/com/InvocationProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | /** 23 | * @version $Id$ 24 | * @author joe 25 | * 26 | * DispatchEvents wraps this class around any event handlers before making the 27 | * JNI call that sets up the link with EventProxy. This means that 28 | * EventProxy.cpp just calls invoke(String,Variant[]) against the instance of 29 | * this class. Then this class does reflection against the event listener to 30 | * call the actual event methods. The event methods can return void or return a 31 | * Variant. Any value returned will be passed back to the calling windows module 32 | * by the Jacob JNI layer. 33 | *

34 | * 35 | * The void returning signature is the standard legacy signature. The Variant 36 | * returning signature was added in 1.10 to support event handlers returning 37 | * values. 38 | * 39 | */ 40 | public abstract class InvocationProxy { 41 | 42 | /** 43 | * the object we will try and forward to. 44 | */ 45 | protected Object mTargetObject = null; 46 | 47 | /** 48 | * dummy constructor for subclasses that don't actually wrap anything and 49 | * just want to override the invoke() method 50 | */ 51 | protected InvocationProxy() { 52 | super(); 53 | } 54 | 55 | /** 56 | * The method actually invoked by EventProxy.cpp. The method name is 57 | * calculated by the underlying JNI code from the MS windows Callback 58 | * function name. The method is assumed to take an array of Variant objects. 59 | * The method may return a Variant or be a void. Those are the only two 60 | * options that will not blow up. 61 | *

62 | * Subclasses that override this should make sure mTargetObject is not null 63 | * before processing. 64 | * 65 | * @param methodName 66 | * name of method in mTargetObject we will invoke 67 | * @param targetParameters 68 | * Variant[] that is the single parameter to the method 69 | * @return an object that will be returned to the com event caller 70 | */ 71 | public abstract Variant invoke(String methodName, 72 | Variant targetParameters[]); 73 | 74 | /** 75 | * used by EventProxy.cpp to create variant objects in the right thread 76 | * 77 | * @return Variant object that will be used by the COM layer 78 | */ 79 | public Variant getVariant() { 80 | return new VariantViaEvent(); 81 | } 82 | 83 | /** 84 | * Sets the target for this InvocationProxy. 85 | * 86 | * @param pTargetObject 87 | * @throws IllegalArgumentException 88 | * if target is not publicly accessible 89 | */ 90 | public void setTarget(Object pTargetObject) { 91 | if (JacobObject.isDebugEnabled()) { 92 | JacobObject.debug("InvocationProxy: setting target " 93 | + pTargetObject); 94 | } 95 | if (pTargetObject != null) { 96 | // JNI code apparently bypasses this check and could operate against 97 | // protected classes. This seems like a security issue... 98 | // maybe it was because JNI code isn't in a package? 99 | if (!java.lang.reflect.Modifier.isPublic(pTargetObject.getClass() 100 | .getModifiers())) { 101 | throw new IllegalArgumentException( 102 | "InvocationProxy only public classes can receive event notifications"); 103 | } 104 | } 105 | mTargetObject = pTargetObject; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/com/jacob/com/JacobException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | /** 23 | * The parent class of all Jacob exceptions. They all used to be based off of 24 | * RuntimeException or ComException but it was decided to base them all off of 25 | * one owned by this project. 26 | */ 27 | public class JacobException extends RuntimeException { 28 | 29 | /** 30 | * 31 | */ 32 | private static final long serialVersionUID = -1637125318746002715L; 33 | 34 | /** 35 | * Default constructor. Calls super with a "No Message Provided" string 36 | */ 37 | public JacobException() { 38 | super("No Message Provided"); 39 | } 40 | 41 | /** 42 | * standard constructor 43 | * 44 | * @param message 45 | */ 46 | public JacobException(String message) { 47 | super(message); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/com/jacob/com/JacobObject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | /** 23 | * The superclass of all Jacob objects. It is used to create a standard API 24 | * framework and to facilitate memory management for Java and COM memory 25 | * elements. 26 | *

27 | * All instances of this class and subclasses are automatically managed by the 28 | * ROT. This means the ROT cannot be a subclass of JacobObject. 29 | *

30 | * All COM object created by JACOB extend this class so that we can 31 | * automatically release them when the thread is detached from COM - if we leave 32 | * it to the finalizer it will call the release from another thread, which may 33 | * result in a segmentation violation. 34 | */ 35 | public class JacobObject { 36 | 37 | /** 38 | * Standard constructor that adds this JacobObject to the memory management 39 | * pool. 40 | */ 41 | public JacobObject() { 42 | ROT.addObject(this); 43 | } 44 | 45 | /** 46 | * Finalizers call this method. This method should release any COM data 47 | * structures in a way that it can be called multiple times. This can happen 48 | * if someone manually calls this and then a finalizer calls it. 49 | */ 50 | public void safeRelease() { 51 | // currently does nothing - subclasses may do something 52 | if (isDebugEnabled()) { 53 | // this used to do a toString() but that is bad for SafeArray 54 | debug("SafeRelease: " + this.getClass().getName()); 55 | } 56 | } 57 | 58 | /** 59 | * When things go wrong, it is useful to be able to debug the ROT. We stash 60 | * this in a static so the getProperty() call only happens once. This can 61 | * blow up with java.security.AccessControlException in a signed applet 62 | * https://sourceforge.net/p/jacob-project/bugs/116/ 63 | */ 64 | private static final boolean DEBUG = 65 | // true; 66 | "true".equalsIgnoreCase(System.getProperty("com.jacob.debug")); 67 | 68 | protected static boolean isDebugEnabled() { 69 | return DEBUG; 70 | } 71 | 72 | /** 73 | * Loads JacobVersion.Properties and returns the value of version in it 74 | * 75 | * @deprecated use JacobReleaseInfo.getBuildDate() instead. 76 | * @return String value of version in JacobVersion.Properties or "" if none 77 | */ 78 | @Deprecated 79 | public static String getBuildDate() { 80 | return JacobReleaseInfo.getBuildDate(); 81 | } 82 | 83 | /** 84 | * Loads JacobVersion.Properties and returns the value of version in it 85 | * 86 | * @deprecated use JacobReleaseInfo.getBuildVersion() instead. 87 | * @return String value of version in JacobVersion.Properties or "" if none 88 | */ 89 | @Deprecated 90 | public static String getBuildVersion() { 91 | return JacobReleaseInfo.getBuildVersion(); 92 | } 93 | 94 | /** 95 | * Very basic debugging function. 96 | * 97 | * @param istrMessage 98 | */ 99 | protected static void debug(String istrMessage) { 100 | if (isDebugEnabled()) { 101 | System.out.println(Thread.currentThread().getName() + ": " 102 | + istrMessage); 103 | } 104 | } 105 | 106 | /** 107 | * force the jacob DLL to be loaded whenever this class is referenced 108 | */ 109 | static { 110 | LibraryLoader.loadJacobLibrary(); 111 | } 112 | 113 | } -------------------------------------------------------------------------------- /src/main/com/jacob/com/JacobReleaseInfo.java: -------------------------------------------------------------------------------- 1 | package com.jacob.com; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.util.Properties; 6 | 7 | /** 8 | * An interface to the version properties file. This code was removed from 9 | * JacobObject because it doesn't belong there. 10 | * 11 | */ 12 | public class JacobReleaseInfo { 13 | 14 | /** 15 | * holds the build version as retrieved from the version properties file 16 | * that exists in the JAR. This can be retrieved by calling the static 17 | * method getBuildVersion() 18 | * 19 | * @see #getBuildVersion() 20 | */ 21 | private static String buildVersion = ""; 22 | /** 23 | * holds the build date as retrieved from the version properties file that 24 | * exists in the JAR This can be retrieved by calling the static method 25 | * getBuildDate() 26 | * 27 | * @see #getBuildDate() 28 | */ 29 | private static String buildDate = ""; 30 | /** the name of the jacob version properties file */ 31 | private static final String PROPERTY_FILE_NAME = "META-INF/JacobVersion.properties"; 32 | 33 | /** 34 | * Loads version information from PROPERTY_FILE_NAME that was built as part 35 | * of this release. 36 | * 37 | * @throws IllegalStateException 38 | * when it can't find the version properties file 39 | */ 40 | private static void loadVersionProperties() { 41 | Properties versionProps = new Properties(); 42 | // can't use system class loader cause won't work in JavaWebStart 43 | InputStream stream = JacobReleaseInfo.class.getClassLoader() 44 | .getResourceAsStream(PROPERTY_FILE_NAME); 45 | // This should never happen. This is an attempt to make something work 46 | // for WebSphere. They may be using some kind of Servlet loader that 47 | // needs an absolute path based search 48 | if (stream == null) { 49 | stream = JacobReleaseInfo.class.getClassLoader() 50 | .getResourceAsStream("/" + PROPERTY_FILE_NAME); 51 | } 52 | // A report came in that WebSphere had trouble finding the file 53 | // so lets trap it. Plus, it's a good idea anyway. 54 | if (stream == null) { 55 | throw new IllegalStateException( 56 | "Can't find " 57 | + PROPERTY_FILE_NAME 58 | + " using JacobReleaseInfo.class.getClassLoader().getResourceAsStream()"); 59 | } else { 60 | try { 61 | versionProps.load(stream); 62 | stream.close(); 63 | buildVersion = (String) versionProps.get("version"); 64 | buildDate = (String) versionProps.get("build.date"); 65 | } catch (IOException ioe) { 66 | ioe.printStackTrace(); 67 | System.err.println("Warning! Couldn't load props " + ioe); 68 | } 69 | } 70 | } 71 | 72 | /** 73 | * loads PROPERT_FILE_NAME and returns the value of version in it 74 | * 75 | * @return String value of version in PROPERT_FILE_NAME or "" if none 76 | */ 77 | public static String getBuildDate() { 78 | if (buildDate.equals("")) { 79 | loadVersionProperties(); 80 | } 81 | return buildDate; 82 | } 83 | 84 | /** 85 | * loads PROPERT_FILE_NAME and returns the value of version in it 86 | * 87 | * @return String value of version in PROPERT_FILE_NAME or "" if none 88 | */ 89 | public static String getBuildVersion() { 90 | if (buildVersion.equals("")) { 91 | loadVersionProperties(); 92 | } 93 | return buildVersion; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/com/jacob/com/MainSTA.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | /** 23 | * We provide our own main sta thread to avoid COM tagging a random thread as 24 | * the main STA - this is the thread in which all Apartment threaded components 25 | * will be created if the client chooses an MTA threading model for the java 26 | * side of the app. 27 | */ 28 | public class MainSTA extends STA { 29 | } -------------------------------------------------------------------------------- /src/main/com/jacob/com/NotImplementedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | /** 23 | * Thrown by java APIs that are not implemented either because they were never 24 | * implemented or because they are being deprecated This is a subclass of 25 | * ComException so callers can still just catch ComException. 26 | */ 27 | public class NotImplementedException extends JacobException { 28 | 29 | /** 30 | * 31 | */ 32 | private static final long serialVersionUID = -9169900832852356445L; 33 | 34 | /** 35 | * @param description 36 | */ 37 | public NotImplementedException(String description) { 38 | super(description); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/com/jacob/com/STA.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | /** 23 | * A class that implements a Single Threaded Apartment. Users will subclass this 24 | * and override OnInit() and OnQuit() where they will create and destroy a COM 25 | * component that wants to run in an STA other than the main STA. 26 | */ 27 | public class STA extends Thread { 28 | /** 29 | * referenced by STA.cpp 30 | */ 31 | public int threadID; 32 | 33 | /** 34 | * constructor for STA 35 | */ 36 | public STA() { 37 | start(); // start the thread 38 | } 39 | 40 | /* 41 | * (non-Javadoc) 42 | * 43 | * @see java.lang.Thread#run() 44 | */ 45 | public void run() { 46 | // init COM 47 | ComThread.InitSTA(); 48 | if (OnInit()) { 49 | // this call blocks in the win32 message loop 50 | // until quitMessagePump is called 51 | doMessagePump(); 52 | } 53 | OnQuit(); 54 | // uninit COM 55 | ComThread.Release(); 56 | } 57 | 58 | /** 59 | * Override this method to create and initialize any COM component that you 60 | * want to run in this thread. If anything fails, return false to terminate 61 | * the thread. 62 | * 63 | * @return always returns true 64 | */ 65 | public boolean OnInit() { 66 | return true; 67 | } 68 | 69 | /** 70 | * Override this method to destroy any resource before the thread exits and 71 | * COM in uninitialized 72 | */ 73 | public void OnQuit() { 74 | // there is nothing to see here 75 | } 76 | 77 | /** 78 | * calls quitMessagePump 79 | */ 80 | public void quit() { 81 | quitMessagePump(); 82 | } 83 | 84 | /** 85 | * run a message pump for the main STA 86 | */ 87 | public native void doMessagePump(); 88 | 89 | /** 90 | * quit message pump for the main STA 91 | */ 92 | public native void quitMessagePump(); 93 | 94 | /** 95 | * STA isn't a subclass of JacobObject so a reference to it doesn't load the 96 | * DLL without this 97 | */ 98 | static { 99 | LibraryLoader.loadJacobLibrary(); 100 | } 101 | } -------------------------------------------------------------------------------- /src/main/com/jacob/com/VariantViaEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | /** 23 | * a public class to variant that is used to track which variant objects are 24 | * created by event callbacks This is solely used for that purpose. 25 | */ 26 | public class VariantViaEvent extends Variant { 27 | 28 | /** 29 | * Standard constructor used by JNI event handling layer 30 | */ 31 | public VariantViaEvent() { 32 | super(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/com/jacob/com/WrongThreadException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004 Sourceforge JACOB Project. 3 | * All rights reserved. Originator: Dan Adler (http://danadler.com). 4 | * Get more information about JACOB at http://sourceforge.net/projects/jacob-project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | package com.jacob.com; 21 | 22 | /** 23 | * thrown in util.cpp 24 | */ 25 | public class WrongThreadException extends JacobException { 26 | /** 27 | * identifier generated by Eclipse 28 | */ 29 | private static final long serialVersionUID = 6308780364980228692L; 30 | 31 | /** 32 | * standard 0 arg constructor with no message 33 | * 34 | */ 35 | public WrongThreadException() { 36 | super("No Message Provided."); 37 | } 38 | 39 | /** 40 | * standard constructor with a string message 41 | * 42 | * @param s 43 | */ 44 | public WrongThreadException(String s) { 45 | super(s); 46 | } 47 | } -------------------------------------------------------------------------------- /src/test/README.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | A lot of these are actually integration tests 4 | 5 | ## Historical 6 | 7 | This directory contains junit tests and other/older tests for 8 | specific functions. Sometimes tests in this directory migrate 9 | to the samples directory as they are updated to show more functionality. -------------------------------------------------------------------------------- /src/test/com/jacob/com/CurrencyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Esmond Pitt, 2024. 3 | * All rights reserved. 4 | */ 5 | package com.jacob.com; 6 | 7 | import static junit.framework.TestCase.assertEquals; 8 | import org.junit.Before; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | import org.junit.rules.TestName; 12 | 13 | /** 14 | * 15 | * @author Esmond Pitt 16 | */ 17 | public class CurrencyTest { 18 | @Rule 19 | public TestName testName = new TestName(); 20 | 21 | @Before 22 | public void setUp() { 23 | System.out.println("CurrencyTest." + testName.getMethodName()); 24 | } 25 | 26 | /** 27 | * Test of longValue method, of class Currency. 28 | */ 29 | @Test 30 | public void testLongValue() { 31 | Currency instance = new Currency(1234567890123456L); 32 | long expResult = 1234567890123456L; 33 | long result = instance.longValue(); 34 | assertEquals(expResult, result); 35 | } 36 | 37 | /** 38 | * Test of compareTo method, of class Currency. 39 | */ 40 | @Test 41 | public void testCompareTo_Currency() { 42 | Currency anotherCurrency = new Currency(1234567890123456L); 43 | Currency instance = new Currency(1234567890000000L); 44 | int expResult = -1; 45 | int result = instance.compareTo(anotherCurrency); 46 | assertEquals(expResult, result); 47 | } 48 | 49 | // /** 50 | // * Test of compareTo method, of class Currency. 51 | // * This test should not compile. 52 | // */ 53 | // @Test 54 | // public void testCompareTo_Object() 55 | // { 56 | // Object o = new Object(); 57 | // Currency instance = new Currency(1234567890123456L); 58 | // int expResult = 0; 59 | // int result = instance.compareTo(o); 60 | // assertEquals(expResult, result); 61 | // } 62 | 63 | /** 64 | * Test of equals method, of class Currency. 65 | */ 66 | @Test 67 | public void testEquals() { 68 | Object o = new Object(); 69 | Currency instance = new Currency(1234567890123456L); 70 | boolean expResult = false; 71 | boolean result = instance.equals(o); 72 | assertEquals(expResult, result); 73 | } 74 | 75 | } -------------------------------------------------------------------------------- /src/test/com/jacob/com/DateUtilitiesTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.com; 2 | 3 | import java.util.Calendar; 4 | import java.util.Date; 5 | import java.util.GregorianCalendar; 6 | 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | 10 | 11 | /** 12 | * test cases that should exercise the new date conversion code 13 | *

14 | * This test does not require any command line options because it is only a 15 | * utility test 16 | */ 17 | 18 | public class DateUtilitiesTest { 19 | 20 | /** 21 | * verify date conversion to and from java 22 | */ 23 | @Test 24 | public void testDateUtilities() { 25 | Date now = new Date(); 26 | double comTimeForNow = DateUtilities.convertDateToWindowsTime(now); 27 | Date retrievedNow = DateUtilities 28 | .convertWindowsTimeToDate(comTimeForNow); 29 | if (!now.equals(retrievedNow)) { 30 | Assert.fail("DateUtilities Date Test failed " + now + " != " 31 | + retrievedNow); 32 | } else { 33 | System.out.println("DateUtilities Date Test passed"); 34 | } 35 | 36 | } 37 | 38 | /** 39 | * Verify that the start of time is when we think it is. 40 | */ 41 | @Test 42 | public void testBeginningOfWindowsTime() { 43 | // this is a magic time in the windows world 44 | Date beginningOfWindowsTime = new GregorianCalendar(1899, 45 | Calendar.DECEMBER, 30).getTime(); 46 | double comTimeForBeginningOfWindowsTime = DateUtilities 47 | .convertDateToWindowsTime(beginningOfWindowsTime); 48 | if (comTimeForBeginningOfWindowsTime > 0) { 49 | Assert.fail("Beginning of windows time test failed " 50 | + comTimeForBeginningOfWindowsTime); 51 | } else { 52 | System.out.println("Beginning of windows time test passed"); 53 | } 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/test/com/jacob/com/DispatchNullProgramIdTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.com; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.test.BaseTestCase; 6 | 7 | /** 8 | * This test verifies that the Dispatch object protects itself when the 9 | * constructor is called with a null program id. Prior to this protection, the 10 | * VM might crash.m 11 | *

12 | * May need to run with some command line options (including from inside 13 | * Eclipse). Look in the docs area at the Jacob usage document for command line 14 | * options. 15 | */ 16 | public class DispatchNullProgramIdTest extends BaseTestCase { 17 | 18 | /** 19 | * Verify that dispatch constructors are protected from null program ids. 20 | */ 21 | @Test 22 | public void testNullProgramId() { 23 | try { 24 | String nullParam = null; 25 | new Dispatch(nullParam); 26 | fail("the dispatch failed to protect itself from null program ids"); 27 | } catch (IllegalArgumentException iae) { 28 | System.out 29 | .println("the dispatch protected itself from null program ids"); 30 | } 31 | try { 32 | String nullParam = ""; 33 | new Dispatch(nullParam); 34 | fail("the dispatch failed to protect itself from empty string program ids"); 35 | } catch (IllegalArgumentException iae) { 36 | System.out 37 | .println("the dispatch protected itself from empty string program ids"); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/com/jacob/com/DispatchTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.com; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.activeX.ActiveXComponent; 6 | import com.jacob.test.BaseTestCase; 7 | 8 | /** 9 | * Test some of the Dispatch utility methods 10 | *

11 | * May need to run with some command line options (including from inside 12 | * Eclipse). Look in the docs area at the Jacob usage document for command line 13 | * options. 14 | */ 15 | public class DispatchTest extends BaseTestCase { 16 | 17 | /** 18 | * Verify this detects word's exit 19 | */ 20 | @Test 21 | public void testDispatchHasExited() { 22 | String pid = "Word.Application"; 23 | ActiveXComponent axc = new ActiveXComponent(pid); 24 | assertEquals(0, Dispatch.hasExited(axc)); 25 | axc.invoke("Quit", new Variant[] {}); 26 | // should take some amount of time for Word to Quit so should = !exited 27 | assertEquals(0, Dispatch.hasExited(axc)); 28 | try { 29 | // sleep some reasonable amount of time waiting for it to quit 30 | Thread.sleep(2000); 31 | } catch (InterruptedException e) { 32 | fail("should not have been interrupted"); 33 | } 34 | assertEquals(1, Dispatch.hasExited(axc)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/com/jacob/com/DispatchValidDispatchTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.com; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.test.BaseTestCase; 6 | 7 | /** 8 | * Test armoring of dispatch static methods 9 | *

10 | * May need to run with some command line options (including from inside 11 | * Eclipse). Look in the docs area at the Jacob usage document for command line 12 | * options. 13 | */ 14 | public class DispatchValidDispatchTest extends BaseTestCase { 15 | 16 | /** 17 | * force an IllegalArgumentException to verify the utility method throws 18 | * correctly. 19 | */ 20 | @Test 21 | public void testThrowIllegalArgumentException() { 22 | try { 23 | Dispatch.call(null, 0); 24 | fail("Failed to throw IllegalArgumentException"); 25 | } catch (IllegalArgumentException iae) { 26 | System.out.println("Caught correct IllegalArgumentException: " 27 | + iae); 28 | } 29 | } 30 | 31 | /** 32 | * force an IllegalStateException to verify the utility method throws 33 | * correctly. 34 | */ 35 | @Test 36 | public void testThrowIllegalStateException() { 37 | try { 38 | Dispatch foo = new Dispatch(); 39 | Dispatch.call(foo, 0); 40 | fail("Failed to throw IllegalStateException"); 41 | } catch (IllegalStateException ise) { 42 | System.out.println("Caught correct IllegalStateException " + ise); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/com/jacob/com/JacobDeadlockTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.com; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.test.BaseTestCase; 6 | 7 | /** 8 | * Sourceforge defect report 1986987 July 2008. This test case demonstrated a 9 | * deadlock issue. 10 | *

    11 | *
  • One thread attempts to create an object in a thread where InitMTA has 12 | * not been called. This results in ROT.addObject being called which then calls 13 | * ComThread.InitMTA 14 | *
  • One thread attempts to call ComThread.release() which then calls ROT 15 | * .clear objects. 16 | *
17 | * The result is one thread with a call sequence ComThread--ROT and the other 18 | * with a sequence ROT--ComThread resulting in deadlock. 19 | *

20 | * This test will fail with debug logging turned on because of the amount of 21 | * time it takes to write the debug output. 22 | * 23 | * @author jsamarziya 24 | * 25 | */ 26 | public class JacobDeadlockTest extends BaseTestCase { 27 | private static final long TIMEOUT = 5000l; 28 | 29 | /** Thread component */ 30 | public static class TestThread extends Thread { 31 | private final int id; 32 | private final boolean initCOM; 33 | private final boolean writeOutput; 34 | 35 | /** 36 | * constructor for ThestThread 37 | * 38 | * @param id 39 | * @param initCOM 40 | * @param writeOutput 41 | * 42 | */ 43 | public TestThread(int id, boolean initCOM, boolean writeOutput) { 44 | this.id = id; 45 | this.initCOM = initCOM; 46 | this.writeOutput = writeOutput; 47 | } 48 | 49 | @Override 50 | public void run() { 51 | for (int i = 0; i < 1000; i++) { 52 | log("iteration " + i); 53 | if (initCOM) { 54 | log("Initializing COM thread"); 55 | ComThread.InitMTA(false); 56 | } 57 | log("Creating JacobObject"); 58 | new JacobObject(); 59 | log("Releasing COM thread"); 60 | ComThread.Release(); 61 | } 62 | log("Exiting Java Thread"); 63 | } 64 | 65 | private void log(String message) { 66 | if (writeOutput) { 67 | System.out.println(Thread.currentThread().getName() 68 | + ": TestThread[" + id + "] " + " " + " - " + message); 69 | } 70 | } 71 | } 72 | 73 | /** 74 | * This test shows that if ComThread.Init() is called explicitly, no problem 75 | * occurs. 76 | * 77 | * @throws InterruptedException 78 | */ 79 | @Test 80 | public void testShowNoProblemIfCOMIsInitialized() 81 | throws InterruptedException { 82 | runTest(2, true, false); 83 | runTest(100, true, false); 84 | } 85 | 86 | /** 87 | * This test shows that if only one thread is creating COM objects, no 88 | * problem occurs. 89 | * 90 | * @throws InterruptedException 91 | */ 92 | @Test 93 | public void testShowNoProblemIfSingleThreaded() throws InterruptedException { 94 | runTest(1, false, false); 95 | runTest(1, true, false); 96 | } 97 | 98 | /** 99 | * Runs the test with two threads, which don't initialize the COM thread. 100 | * 101 | * This test will always fail. 102 | * 103 | * @throws InterruptedException 104 | */ 105 | @Test 106 | public void testShowDeadlockProblem() throws InterruptedException { 107 | runTest(2, false, true); 108 | } 109 | 110 | private void runTest(int numberOfThreads, boolean initCOM, 111 | boolean writeOutput) throws InterruptedException { 112 | Thread[] threads = new Thread[numberOfThreads]; 113 | for (int i = 0; i < threads.length; i++) { 114 | threads[i] = new TestThread(i, initCOM, writeOutput); 115 | threads[i].start(); 116 | } 117 | for (int i = 0; i < threads.length; i++) { 118 | threads[i].join(TIMEOUT); 119 | if (threads[i].isAlive()) { 120 | fail("thread " + i + " failed to finish in " + TIMEOUT 121 | + " milliseconds"); 122 | } 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/test/com/jacob/com/JacobObjectTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.com; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.test.BaseTestCase; 6 | 7 | /** 8 | * This will eventually be changed to a unit test. 9 | *

10 | * May need to run with some command line options (including from inside 11 | * Eclipse). Look in the docs area at the Jacob usage document for command line 12 | * options. 13 | */ 14 | public class JacobObjectTest extends BaseTestCase { 15 | 16 | /** 17 | * verify the build version and date functions work correctly 18 | */ 19 | @Test 20 | public void testBuildVersion() { 21 | System.out.println("build version is " + JacobReleaseInfo.getBuildVersion()); 22 | System.out.println("build date is " + JacobReleaseInfo.getBuildDate()); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/com/jacob/com/LibraryLoaderTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.com; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | /** 7 | * Tests Library loader architecture methods This test requires that jacob.jar 8 | * be compiled and added to the classpath. You will need to refresh the release 9 | * directory so that eclipse knows about jacob.jar. Otherwise you will get a 10 | * "jar not found" dialog. 11 | * 12 | *

13 | * May need to run with some command line options (including from inside 14 | * Eclipse). Look in the docs area at the Jacob usage document for command line 15 | * options. 16 | * 17 | * @author clay_shooter 18 | * 19 | */ 20 | public class LibraryLoaderTest { 21 | 22 | /** 23 | * verify the architecture switches work 24 | */ 25 | @Test 26 | public void testArchitectureVersions() { 27 | System.out.println("running on 32Bit? VM" 28 | + LibraryLoader.shouldLoad32Bit()); 29 | // verify no null pointer is thrown 30 | LibraryLoader.shouldLoad32Bit(); 31 | } 32 | 33 | /** 34 | * verify LibraryLoader.JACOB_DLL_NAME is read by LibraryLoader 35 | */ 36 | @Test 37 | public void testJacobDllNameSystemProperty() { 38 | // this test used to run in the reverse order but that caused 39 | // ClassDefNotFound on DEBUG 40 | 41 | // no way to clear a system property once set so lets try setting to 42 | // default 43 | System.setProperty(LibraryLoader.JACOB_DLL_NAME, LibraryLoader 44 | .getPreferredDLLName()); 45 | try { 46 | LibraryLoader.loadJacobLibrary(); 47 | } catch (UnsatisfiedLinkError ule) { 48 | Assert.fail("Should have been able to load dll after setting " 49 | + LibraryLoader.JACOB_DLL_NAME + " to " 50 | + LibraryLoader.getPreferredDLLName() + " " 51 | + ule.getMessage()); 52 | } 53 | 54 | // fill with bad dll name and try again 55 | System.setProperty(LibraryLoader.JACOB_DLL_NAME, "xxx"); 56 | try { 57 | LibraryLoader.loadJacobLibrary(); 58 | Assert.fail("Should have been unable to load dll with name xxx"); 59 | } catch (UnsatisfiedLinkError ule) { 60 | System.out.println("correctly caught UnsatisfiedLinkError"); 61 | // yes, this is what we want to see when using a bad name 62 | } 63 | } 64 | 65 | /** 66 | * Verifies that we get a preferred DLL name with X86 since we really only 67 | * run the unit tests on 32 bit platforms. 68 | */ 69 | @Test 70 | public void testDLLNameContainsProcessorAndVersion() { 71 | System.out.println(LibraryLoader.getPreferredDLLName()); 72 | if (LibraryLoader.shouldLoad32Bit()) { 73 | // we build the package and run the unit tests on X86 74 | Assert.assertTrue(LibraryLoader.getPreferredDLLName() 75 | + "should have contained " 76 | + LibraryLoader.DLL_NAME_MODIFIER_32_BIT, 77 | LibraryLoader 78 | .getPreferredDLLName().contains( 79 | LibraryLoader.DLL_NAME_MODIFIER_32_BIT)); 80 | } else { 81 | // we build the package and run the unit tests on X86 82 | Assert.assertTrue(LibraryLoader.getPreferredDLLName() 83 | + "should have contained " 84 | + LibraryLoader.DLL_NAME_MODIFIER_64_BIT, 85 | LibraryLoader 86 | .getPreferredDLLName().contains( 87 | LibraryLoader.DLL_NAME_MODIFIER_64_BIT)); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/test/com/jacob/com/README.md: -------------------------------------------------------------------------------- 1 | This package exists in case folks need to test the Jacob COM objects and need access to protected methods -------------------------------------------------------------------------------- /src/test/com/jacob/com/ROT2Test.java: -------------------------------------------------------------------------------- 1 | package com.jacob.com; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.test.BaseTestCase; 6 | 7 | /** 8 | * This test class exists to test the WeakRefernce implementation . 9 | * 10 | * It is not useful if there isn't one at this time 11 | * 12 | *

13 | * May need to run with some command line options (including from inside 14 | * Eclipse). Look in the docs area at the Jacob usage document for command line 15 | * options. 16 | */ 17 | public class ROT2Test extends BaseTestCase { 18 | 19 | /** 20 | * runs a multi-threaded test 21 | */ 22 | @Test 23 | public void testDoesNotBlowUp() { 24 | ROT2TestThread threads[] = new ROT2TestThread[4]; 25 | for (int i = 0; i < threads.length; i++) { 26 | threads[i] = new ROT2TestThread("thread-" + i, 3000); 27 | } 28 | for (int i = 0; i < threads.length; i++) { 29 | threads[i].start(); 30 | } 31 | } 32 | 33 | /** 34 | * This will try and exercise the thread support in the ROT 35 | */ 36 | 37 | public class ROT2TestThread extends Thread { 38 | private java.util.List ThreadObjects; 39 | 40 | private int initialRunSize = 0; 41 | 42 | /** 43 | * @param arg0 44 | * @param iStartCount 45 | * the initial number of threads 46 | */ 47 | public ROT2TestThread(String arg0, int iStartCount) { 48 | super(arg0); 49 | initialRunSize = iStartCount; 50 | 51 | } 52 | 53 | /** 54 | * A semi-complex series of steps to put the ROT under stress. 1) 55 | * discard half the objects we've created 2) if size is greater than 1 56 | * but not a even number, add 1 new object 3) stop when size is 1. 57 | * 58 | * @see java.lang.Runnable#run() 59 | */ 60 | public void run() { 61 | // something that keeps object references around 62 | // so the gc can't collect them 63 | // we need to create these in the thread so they end up in the right 64 | // ROT table 65 | ThreadObjects = new java.util.ArrayList(initialRunSize); 66 | for (int i = 0; i < initialRunSize; i++) { 67 | // create the object 68 | Variant aNewVariant = new Variant(getName() + "_" + i); 69 | 70 | // create a hard reference to it 71 | ThreadObjects.add(aNewVariant); 72 | } 73 | 74 | while (ThreadObjects.size() > 1) { 75 | String message = ""; 76 | message = getName() + " Workingset=" + ThreadObjects.size() 77 | + " ROT: "; 78 | message += "(before additions and gc " 79 | + ROT.getThreadObjects(false).size() + ")"; 80 | // if there is an odd number of objects greater than 2 81 | if (ThreadObjects.size() > 2 && ThreadObjects.size() % 2 != 0) { 82 | // add a new object 83 | Variant aNewVariant = new Variant(getName() + "_*" 84 | + ThreadObjects.size()); 85 | ThreadObjects.add(aNewVariant); 86 | } 87 | // now iterate across all the objects in our list 88 | for (int i = ThreadObjects.size(); i > 0; i--) { 89 | // removing every other one? 90 | if (i % 2 == 0) { 91 | // remove the reference so gc can get it 92 | ThreadObjects.remove(i - 1); 93 | } 94 | 95 | } 96 | 97 | try { 98 | // simulate the system under load and run the GC 99 | // should end up with weak references with no objects 100 | // attached 101 | Thread.sleep(9); 102 | } catch (InterruptedException e) { 103 | // the VM doesn't want us to sleep anymore, 104 | // so get back to work 105 | } 106 | message += " (before gc, after additions " 107 | + ROT.getThreadObjects(false).size() + ")"; 108 | System.gc(); 109 | message += " (after System.gc " 110 | + ROT.getThreadObjects(false).size() + ")"; 111 | System.out.println(message); 112 | } 113 | } 114 | 115 | /** 116 | * Another test would be to override this to always return the same 117 | * name. That would really screw the ROT! 118 | * 119 | * @see java.lang.Object#toString() 120 | */ 121 | public String toString() { 122 | return super.toString(); 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /src/test/com/jacob/com/VariantDateTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.com; 2 | 3 | import java.util.Date; 4 | 5 | import org.junit.Test; 6 | 7 | import com.jacob.test.BaseTestCase; 8 | 9 | /** 10 | * test cases that should exercise the new date conversion code 11 | *

12 | * May need to run with some command line options (including from inside 13 | * Eclipse). Look in the docs area at the Jacob usage document for command line 14 | * options. 15 | */ 16 | public class VariantDateTest extends BaseTestCase { 17 | 18 | /** 19 | * verify the conversion of Variants into java dates 20 | */ 21 | @Test 22 | public void testVariantDate() { 23 | Date now = new Date(); 24 | Variant holder = new Variant(); 25 | holder.putDate(now); 26 | Date retrievedNow = holder.getJavaDate(); 27 | if (!now.equals(retrievedNow)) { 28 | fail("Variant Date Test failed " + now + " != " + retrievedNow); 29 | } else { 30 | System.out.println("Variant Date Test passed"); 31 | } 32 | 33 | } 34 | 35 | /** 36 | * verify that the Variant constructor accepts Java dates and converts them 37 | * correctly 38 | */ 39 | @Test 40 | public void testVariantDateToJavaObject() { 41 | Date now = new Date(); 42 | Variant holder = new Variant(now); 43 | for (int i = 0; i < 30000; i++) { 44 | Variant dateVariant = new Variant(now); 45 | Date retrievedNow = holder.getJavaDate(); 46 | retrievedNow = dateVariant.getJavaDate(); 47 | if (!now.equals(retrievedNow)) { 48 | fail("Variant Date Test (1) failed " + now + " != " 49 | + retrievedNow); 50 | } else { 51 | // System.out.println("Variant Date Test (1) passed"); 52 | } 53 | // verify auto typecasting works 54 | retrievedNow = (Date) dateVariant.toJavaObject(); 55 | if (!now.equals(retrievedNow)) { 56 | fail("Variant Date Test (2) failed " + now + " != " 57 | + retrievedNow); 58 | } else { 59 | // System.out.println("Variant Date Test (2) passed 60 | // "+retrievedNow); 61 | } 62 | 63 | Variant intVariant = new Variant(4); 64 | Object variantReturn = intVariant.toJavaObject(); 65 | // degenerate test to make sure date isn't always returned 66 | if (variantReturn instanceof Date) { 67 | System.out.println("int variant returned date"); 68 | } 69 | } 70 | System.out.print("Test finished. All tests passed."); 71 | 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/test/com/jacob/test/errors/UnicodeErrorTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.errors; 2 | 3 | import com.jacob.test.BaseTestCase; 4 | 5 | import org.junit.Test; 6 | 7 | import com.jacob.activeX.ActiveXComponent; 8 | import com.jacob.com.ComException; 9 | 10 | /** 11 | * This test verifies patch SF 1794811 . It shows how unicode filenames throw 12 | * exceptions in 1.13M4 and earlier. 13 | * 14 | * @author justme84 15 | * 16 | */ 17 | public class UnicodeErrorTest extends BaseTestCase { 18 | 19 | /** 20 | * verifies that messages can now have unicode in them like when the file 21 | * names have unicode characters 22 | */ 23 | @Test 24 | public void testUnicodeCharactersInErrorMessage() { 25 | ActiveXComponent application = new ActiveXComponent("Word.Application"); 26 | ActiveXComponent documents = application 27 | .getPropertyAsComponent("Documents"); 28 | String fileName = "abc\u0411\u0412\u0413\u0414def"; 29 | try { 30 | documents.invoke("Open", fileName); 31 | fail("Should have thrown an exception"); 32 | } catch (ComException e) { 33 | assertTrue("Error message should contain file name with unicode " 34 | + "characters in it. " + e.getMessage(), 35 | e.getMessage() 36 | .indexOf(fileName) > 0); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/test/com/jacob/test/events/WordEventTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.events; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.activeX.ActiveXComponent; 6 | import com.jacob.com.ComException; 7 | import com.jacob.com.DispatchEvents; 8 | import com.jacob.com.InvocationProxy; 9 | import com.jacob.com.Variant; 10 | import com.jacob.test.BaseTestCase; 11 | 12 | /** 13 | * This test was lifted from a forum posting and shows how you can't listen to 14 | * Excel events (added post 1.9.1 Eclipse Settings.) That test was modified make 15 | * this a MSWord event listener to demonstrate that the InvocationProxy code 16 | * works with MS Word Events This also uses the 1.10 InvocationProxy to receive 17 | * the events. 18 | *

19 | * May need to run with some command line options (including from inside 20 | * Eclipse). Look in the docs area at the Jacob usage document for command line 21 | * options. 22 | */ 23 | public class WordEventTest extends BaseTestCase { 24 | 25 | /** 26 | * load up word, register for events and make stuff happen 27 | * 28 | * @param args 29 | */ 30 | @Test 31 | public void testCaptureWordEvents() { 32 | String pid = "Word.Application"; 33 | String typeLibLocation = null; 34 | 35 | // Grab The Component. 36 | ActiveXComponent axc = new ActiveXComponent(pid); 37 | try { 38 | // Add a listener (doesn't matter what it is). 39 | DispatchEvents de; 40 | if (typeLibLocation == null) { 41 | de = new DispatchEvents(axc, new WordEventTest()); 42 | } else { 43 | de = new DispatchEvents(axc, new WordEventTest(), pid, 44 | typeLibLocation); 45 | } 46 | if (de == null) { 47 | fail("No exception thrown but no dispatch returned for Word events"); 48 | } else { 49 | // Yea! 50 | System.out.println("Successfully attached to " + pid); 51 | 52 | } 53 | // this is different from the ExcelEventTest because it uses 54 | // the jacob active X api instead of the Dispatch api 55 | System.out.println("version=" + axc.getPropertyAsString("Version")); 56 | axc.setProperty("Visible", true); 57 | ActiveXComponent documents = axc 58 | .getPropertyAsComponent("Documents"); 59 | if (documents == null) { 60 | fail("unable to get documents"); 61 | } 62 | axc.invoke("Quit", new Variant[] {}); 63 | 64 | } catch (ComException cfe) { 65 | cfe.printStackTrace(); 66 | fail("Failed to attach to " + pid + ": " + cfe.getMessage()); 67 | 68 | } 69 | System.out 70 | .println("Someone needs to add some MSWord commands to this to " 71 | + "make some on screen stuff happens so the tester " 72 | + "thinks we tested something"); 73 | } 74 | 75 | /** 76 | * a class that receives messages from word 77 | */ 78 | public class WordEvents extends InvocationProxy { 79 | /** 80 | * Constructor so we can create an instance that implements invoke() 81 | */ 82 | public WordEvents() { 83 | } 84 | 85 | /** 86 | * override the invoke() method to log all the events without writing a 87 | * bunch of code 88 | */ 89 | public Variant invoke(String methodName, Variant targetParameter[]) { 90 | System.out.println("Received event from Windows program" 91 | + methodName); 92 | return null; 93 | } 94 | 95 | } 96 | } -------------------------------------------------------------------------------- /src/test/com/jacob/test/excel/teste.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/src/test/com/jacob/test/excel/teste.xls -------------------------------------------------------------------------------- /src/test/com/jacob/test/powerpoint/test1.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/src/test/com/jacob/test/powerpoint/test1.ppt -------------------------------------------------------------------------------- /src/test/com/jacob/test/powerpoint/test2.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/src/test/com/jacob/test/powerpoint/test2.ppt -------------------------------------------------------------------------------- /src/test/com/jacob/test/powerpoint/test3.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/src/test/com/jacob/test/powerpoint/test3.ppt -------------------------------------------------------------------------------- /src/test/com/jacob/test/powerpoint/test4.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/src/test/com/jacob/test/powerpoint/test4.ppt -------------------------------------------------------------------------------- /src/test/com/jacob/test/powerpoint/test5.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/src/test/com/jacob/test/powerpoint/test5.ppt -------------------------------------------------------------------------------- /src/test/com/jacob/test/safearray/SafeArrayBasicTest.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/src/test/com/jacob/test/safearray/SafeArrayBasicTest.java -------------------------------------------------------------------------------- /src/test/com/jacob/test/safearray/SafeArrayDispatchTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.safearray; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.activeX.ActiveXComponent; 6 | import com.jacob.com.ComException; 7 | import com.jacob.com.Dispatch; 8 | import com.jacob.com.SafeArray; 9 | import com.jacob.com.Variant; 10 | import com.jacob.test.BaseTestCase; 11 | 12 | /** 13 | * Test class to verify dispatch with SafeArray 14 | */ 15 | public class SafeArrayDispatchTest extends BaseTestCase { 16 | @Test 17 | public void testDispatchWithSafeArray() { 18 | try { 19 | String scriptCommand = "1+(2*4)-3"; 20 | String lang = "VBScript"; 21 | ActiveXComponent sControl = new ActiveXComponent("ScriptControl"); 22 | Dispatch.put(sControl, "Language", lang); 23 | 24 | Variant result = Dispatch.call(sControl, "Eval", scriptCommand); 25 | assertTrue(result.toString().equals("6")); 26 | 27 | // wrap the script control in a variant 28 | Variant v = new Variant(sControl); 29 | 30 | // create a safe array of type dispatch 31 | SafeArray sa = new SafeArray(Variant.VariantDispatch, 1); 32 | 33 | // put the variant in the array 34 | sa.setVariant(0, v); 35 | 36 | // take it back out 37 | Variant v2 = sa.getVariant(0); 38 | Dispatch d = v2.toDispatch(); 39 | 40 | // make sure you can call eval on it 41 | result = Dispatch.call(d, "Eval", scriptCommand); 42 | assertTrue(result.toString().equals("6")); 43 | } catch (ComException e) { 44 | e.printStackTrace(); 45 | fail("script failure " + e); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/com/jacob/test/safearray/SafeArrayReleaseTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.safearray; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.com.ComThread; 6 | import com.jacob.com.SafeArray; 7 | import com.jacob.com.Variant; 8 | import com.jacob.test.BaseTestCase; 9 | 10 | /** 11 | *

12 | * May need to run with some command line options (including from inside 13 | * Eclipse). Look in the docs area at the Jacob usage document for command line 14 | * options. 15 | *

16 | * SF 1085370 In my understatnding, an instance of SafeArray java class has a 17 | * value of a pointer to VARIANT structure that contains a pointer to a 18 | * SAFEARRAY strucuture. 19 | * 20 | * On the other hand, we can create a Variant object from the SafeArray object 21 | * like this: SafeArray sa = ...; Variant val = new Variant(sa); the val object 22 | * has a pointer to another VARIANT structure that contains a pointer to the 23 | * same SAFEARRAY structure. 24 | * 25 | * In this case, the val object has a pointer to another VARIANT that contains a 26 | * pointer to the same SAFEARRAY like this: 27 | * 28 | * +-----------+ |SafeArray | +------------+ | m_pV--->VARIANT(a) | 29 | * +-----------+ | VT_ARRAY| +---------+ | parray---->SAFEARRAY| +------------+ 30 | * +^--------+ | +-----------+ | |Variant | +------------+ | | 31 | * m_pVariant--->VARIANT(b) | | +-----------+ | VT_ARRAY| | | parray-----+ 32 | * +------------+ 33 | * 34 | * When previous objects are rereased by ComThread.Release(), first the 35 | * VARIANT(a) is released by VariantClear() function, and second the VARIANT(b) 36 | * is released by VariantClear() function too. But the SAFEARRAY was already 37 | * released by the VARIANT(a). 38 | * 39 | * So, in my enviroment (WinXP + J2SDK 1.4.1) the following java program is 40 | * sometimes crash with EXCEPTION_ACCESS_VIOLATION. 41 | * 42 | * 43 | * To solve this problem, it is nessesary to copy the SAFEARRAY like this: 44 | * 45 | * +-----------+ |Variant | +------------+ | m_pVariant--->VARIANT(a) | 46 | * +-----------+ | VT_ARRAY| +---------+ | parray---->SAFEARRAY| +------------+ 47 | * +|--------+ | +-----------+ | copySA() |SafeArray | +------------+ | | 48 | * m_pV--->VARIANT(b) | V +-----------+ | VT_ARRAY| +---------+ | 49 | * parray---->SAFEARRAY| +------------+ +---------+ 50 | * 51 | *

52 | * May need to run with some command line options (including from inside 53 | * Eclipse). Look in the docs area at the Jacob usage document for command line 54 | * options. 55 | */ 56 | 57 | public class SafeArrayReleaseTest extends BaseTestCase { 58 | final static int MAX = 300; 59 | 60 | /** 61 | * verifies the release works on SafeArray 62 | */ 63 | @Test 64 | public void testSaveArrayRelease() { 65 | int count; 66 | System.out.println("Starting test for max = " + MAX); 67 | for (count = 1; count < MAX; count++) { 68 | int i = 0; 69 | try { 70 | ComThread.InitMTA(); 71 | for (i = 0; i < count; i++) { 72 | SafeArray a1 = new SafeArray(Variant.VariantVariant, 2); 73 | a1.setVariant(0, new Variant("foo")); 74 | a1.setVariant(1, new Variant("bar")); 75 | Variant v = new Variant(a1); 76 | SafeArray a2 = v.toSafeArray(true); 77 | if (a2 == null) { 78 | System.out.println("got null back from toSafeArray()"); 79 | } 80 | } 81 | ComThread.Release(); 82 | System.gc(); 83 | // System.out.print("."); 84 | } catch (Exception e) { 85 | fail("Test fails with i = " + i + " (max = " + MAX + ")"); 86 | } 87 | } 88 | System.gc(); 89 | System.out.println("\nTest ends with count = " + count + " (max = " 90 | + MAX + ")"); 91 | } 92 | } -------------------------------------------------------------------------------- /src/test/com/jacob/test/safearray/SafeArrayStringConstructorTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.safearray; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.com.SafeArray; 6 | import com.jacob.test.BaseTestCase; 7 | 8 | /** 9 | * Test case provided #41 Fix for SafeArray(String) constructor 10 | * 11 | * In the current release of Jacob, SafeArray.java contains a constructor which 12 | * takes a string as a single argument. The documentation claims that this 13 | * method converts a string to a VT_UI1 array. Using this method as written 14 | * always causes a ComFailException, because it attempts to create a SafeArray 15 | * from Java chars, which are 16-bit unsigned integers (which would be VT_UI2). 16 | */ 17 | public class SafeArrayStringConstructorTest extends BaseTestCase { 18 | 19 | @Test 20 | public void testStringConstructor() { 21 | // The line below will throw ComFailException using jacob 1.17-M2 22 | // without the patch. 23 | SafeArray safeArrayFromString = new SafeArray("This is a string."); 24 | String convertBack = safeArrayFromString.asString(); 25 | assertEquals("This is a string.", convertBack); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/com/jacob/test/safearray/SafeArrayViaExcel.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freemansoft/jacob-project/61017dbbcc2aa9abbb5ce1028f99cd71ee052fc9/src/test/com/jacob/test/safearray/SafeArrayViaExcel.xls -------------------------------------------------------------------------------- /src/test/com/jacob/test/safearray/SafeArrayViaExcelTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.safearray; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.activeX.ActiveXComponent; 6 | import com.jacob.com.Dispatch; 7 | import com.jacob.com.SafeArray; 8 | import com.jacob.com.Variant; 9 | import com.jacob.test.BaseTestCase; 10 | 11 | /** 12 | * This does simple tests with SafeArray using Excel as a source 13 | *

14 | * May need to run with some command line options (including from inside 15 | * Eclipse). Look in the docs area at the Jacob usage document for command line 16 | * options. 17 | *

18 | * This relies on BaseTestCase to provide the root path to the file under test 19 | */ 20 | public class SafeArrayViaExcelTest extends BaseTestCase { 21 | 22 | /** 23 | * verify safe arrays work with standard applications, Excel in this case 24 | */ 25 | @Test 26 | public void testSafeArrayViaExcel() { 27 | 28 | ActiveXComponent xl = new ActiveXComponent("Excel.Application"); 29 | try { 30 | Dispatch cell; 31 | SafeArray sAProdText; 32 | Dispatch workbooks = xl.getProperty("Workbooks").toDispatch(); 33 | System.out.println("have workbooks"); 34 | Dispatch workbook = Dispatch.call( 35 | workbooks, 36 | "Open", 37 | getWindowsFilePathToPackageResource( 38 | "SafeArrayViaExcel.xls", this.getClass())) 39 | .toDispatch(); 40 | System.out.println("Opened File - SafeArrayViaExcel.xls\n"); 41 | Dispatch sheet = Dispatch.get(workbook, "ActiveSheet").toDispatch(); 42 | cell = Dispatch.invoke(sheet, "Range", Dispatch.Get, 43 | new Object[] { "A1:D1000" }, new int[1]).toDispatch(); 44 | System.out.println("have cell:" + cell); 45 | sAProdText = Dispatch.get(cell, "Value").toSafeArray(); 46 | System.out.println("sa: dim=" + sAProdText.getNumDim()); 47 | System.out.println("sa: start row=" + sAProdText.getLBound(1)); 48 | System.out.println("sa: start col=" + sAProdText.getLBound(2)); 49 | System.out.println("sa: end row=" + sAProdText.getUBound(1)); 50 | System.out.println("sa: end col=" + sAProdText.getUBound(2)); 51 | int i; 52 | int lineNumber = 1; 53 | int n = 0; 54 | for (lineNumber = 1; lineNumber < 1000; lineNumber++) { 55 | for (i = 1; i < 4; i++) { 56 | System.out.println((n++) + " " + lineNumber + " " + i + " " 57 | + sAProdText.getString(lineNumber, i)); 58 | /* 59 | * if (sAProdText.getString(lineNumber,i).compareTo("aaaa") != 60 | * 0 ) { System.out.println("Invalid String in line " + 61 | * lineNumber + " Cell " + i + " Value = " + 62 | * sAProdText.getString(lineNumber,i)); stringFound = false; } } 63 | * if (stringFound) { System.out.println("Valid Strings in 64 | * line " + lineNumber); lineNumber++; } 65 | */ 66 | } 67 | } 68 | 69 | Dispatch.call(workbook, "Close"); 70 | System.out.println("Closed File\n"); 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | fail("Caught Exception " + e); 74 | } finally { 75 | xl.invoke("Quit", new Variant[] {}); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/test/com/jacob/test/vbscript/ScriptTest.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.vbscript; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.activeX.ActiveXComponent; 6 | import com.jacob.com.ComException; 7 | import com.jacob.com.ComThread; 8 | import com.jacob.com.Dispatch; 9 | import com.jacob.com.DispatchEvents; 10 | import com.jacob.com.Variant; 11 | import com.jacob.test.BaseTestCase; 12 | 13 | /** 14 | * In this case the component is created and used in the same thread and it's an 15 | * Apartment Threaded component, so we call InitSTA. 16 | *

17 | * May need to run with some command line options (including from inside 18 | * Eclipse). Look in the docs area at the Jacob usage document for command line 19 | * options. 20 | */ 21 | public class ScriptTest extends BaseTestCase { 22 | 23 | @Test 24 | public void testStupidSpeedTest() { 25 | String lang = "VBScript"; 26 | ActiveXComponent sC = new ActiveXComponent("ScriptControl"); 27 | Dispatch sControl = sC.getObject(); 28 | Dispatch.put(sControl, "Language", lang); 29 | for (int i = 0; i < 10000; i++) { 30 | Dispatch.call(sControl, "Eval", "1+1"); 31 | } 32 | } 33 | 34 | @Test 35 | public void testCreatingDispatchEvents() { 36 | ComThread.InitSTA(true); 37 | DispatchEvents de = null; 38 | Dispatch sControl = null; 39 | 40 | try { 41 | String scriptCommand = getSampleVPScriptForEval(); 42 | String lang = "VBScript"; 43 | ActiveXComponent sC = new ActiveXComponent("ScriptControl"); 44 | sControl = sC.getObject(); 45 | Dispatch.put(sControl, "Language", lang); 46 | ScriptTestErrEvents te = new ScriptTestErrEvents(); 47 | de = new DispatchEvents(sControl, te); 48 | if (de == null) { 49 | System.out 50 | .println("Received null when trying to create new DispatchEvents"); 51 | } 52 | Variant result = Dispatch.call(sControl, "Eval", scriptCommand); 53 | // call it twice to see the objects reused 54 | result = Dispatch.call(sControl, "Eval", scriptCommand); 55 | // call it 3 times to see the objects reused 56 | result = Dispatch.call(sControl, "Eval", scriptCommand); 57 | System.out.println("eval(" + scriptCommand + ") = " + result); 58 | } catch (ComException e) { 59 | e.printStackTrace(); 60 | fail("Caught Exception " + e); 61 | } finally { 62 | Integer I = null; 63 | for (int i = 1; i < 1000000; i++) { 64 | I = new Integer(i); 65 | } 66 | System.out.println(I); 67 | ComThread.Release(); 68 | ComThread.quitMainSTA(); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/com/jacob/test/vbscript/ScriptTest2.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.vbscript; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.activeX.ActiveXComponent; 6 | import com.jacob.com.ComException; 7 | import com.jacob.com.ComThread; 8 | import com.jacob.com.Dispatch; 9 | import com.jacob.com.DispatchEvents; 10 | import com.jacob.com.DispatchProxy; 11 | import com.jacob.com.STA; 12 | import com.jacob.com.Variant; 13 | import com.jacob.test.BaseTestCase; 14 | 15 | /** 16 | * This example demonstrates how to make calls between two different STA's. 17 | * First, to create an STA, you need to extend the STA class and override its 18 | * OnInit() method. This method will be called in the STA's thread so you can 19 | * use it to create your COM components that will run in that STA. If you then 20 | * try to call methods on those components from other threads (STA or MTA) - 21 | * this will fail. You cannot create a component in an STA and call its methods 22 | * from another thread. You can use the DispatchProxy to get a proxy to any 23 | * Dispatch that lives in another STA. This object has to be created in the STA 24 | * that houses the Dispatch (in this case it's created in the OnInit method). 25 | * Then, another thread can call the toDispatch() method of DispatchProxy to get 26 | * a local proxy. At most ONE (!) thread can call toDispatch(), and the call can 27 | * be made only once. This is because a IStream object is used to pass the 28 | * proxy, and it is only written once and closed when you read it. If you need 29 | * multiple threads to access a Dispatch pointer, then create that many 30 | * DispatchProxy objects. 31 | *

32 | * May need to run with some command line options (including from inside 33 | * Eclipse). Look in the docs area at the Jacob usage document for command line 34 | * options. 35 | */ 36 | 37 | public class ScriptTest2 extends BaseTestCase { 38 | @Test 39 | public void testScript2() { 40 | try { 41 | ComThread.InitSTA(); 42 | ScriptTestSTA script = new ScriptTestSTA(); 43 | try { 44 | Thread.sleep(1000); 45 | } catch (InterruptedException ie) { 46 | // should we get this? 47 | } 48 | 49 | String scriptCommand = getSampleVPScriptForEval(); 50 | // get a thread-local Dispatch from sCon 51 | Dispatch sc = script.sCon.toDispatch(); 52 | 53 | // call a method on the thread-local Dispatch obtained 54 | // from the DispatchProxy. If you try to make the same 55 | // method call on the sControl object - you will get a 56 | // ComException. 57 | Variant result = Dispatch.call(sc, "Eval", scriptCommand); 58 | System.out.println("eval(" + scriptCommand + ") = " + result); 59 | script.quit(); 60 | System.out.println("called quit"); 61 | } catch (ComException e) { 62 | e.printStackTrace(); 63 | fail("caught exception" + e); 64 | } finally { 65 | Integer I = null; 66 | for (int i = 1; i < 1000000; i++) { 67 | I = new Integer(i); 68 | } 69 | System.out.println(I); 70 | ComThread.Release(); 71 | } 72 | } 73 | 74 | public class ScriptTestSTA extends STA { 75 | 76 | public DispatchEvents de = null; 77 | 78 | public Dispatch sControl = null; 79 | 80 | public DispatchProxy sCon = null; 81 | 82 | public boolean OnInit() { 83 | try { 84 | System.out.println("OnInit"); 85 | System.out.println(Thread.currentThread()); 86 | String lang = "VBScript"; 87 | sControl = new ActiveXComponent("ScriptControl"); 88 | 89 | // sCon can be called from another thread 90 | sCon = new DispatchProxy(sControl); 91 | 92 | Dispatch.put(sControl, "Language", lang); 93 | ScriptTestErrEvents te = new ScriptTestErrEvents(); 94 | de = new DispatchEvents(sControl, te); 95 | return true; 96 | } catch (Exception e) { 97 | e.printStackTrace(); 98 | return false; 99 | } 100 | } 101 | 102 | public void OnQuit() { 103 | System.out.println("OnQuit"); 104 | } 105 | 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/test/com/jacob/test/vbscript/ScriptTest2ActiveX.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.vbscript; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.activeX.ActiveXComponent; 6 | import com.jacob.com.ComException; 7 | import com.jacob.com.ComThread; 8 | import com.jacob.com.DispatchEvents; 9 | import com.jacob.com.DispatchProxy; 10 | import com.jacob.com.STA; 11 | import com.jacob.com.Variant; 12 | import com.jacob.test.BaseTestCase; 13 | 14 | /** 15 | * This example demonstrates how to make calls between two different STA's. 16 | * First, to create an STA, you need to extend the STA class and override its 17 | * OnInit() method. This method will be called in the STA's thread so you can 18 | * use it to create your COM components that will run in that STA. If you then 19 | * try to call methods on those components from other threads (STA or MTA) - 20 | * this will fail. You cannot create a component in an STA and call its methods 21 | * from another thread. You can use the DispatchProxy to get a proxy to any 22 | * Dispatch that lives in another STA. This object has to be created in the STA 23 | * that houses the Dispatch (in this case it's created in the OnInit method). 24 | * Then, another thread can call the toDispatch() method of DispatchProxy to get 25 | * a local proxy. At most ONE (!) thread can call toDispatch(), and the call can 26 | * be made only once. This is because a IStream object is used to pass the 27 | * proxy, and it is only written once and closed when you read it. If you need 28 | * multiple threads to access a Dispatch pointer, then create that many 29 | * DispatchProxy objects. 30 | *

31 | * May need to run with some command line options (including from inside 32 | * Eclipse). Look in the docs area at the Jacob usage document for command line 33 | * options. 34 | */ 35 | public class ScriptTest2ActiveX extends BaseTestCase { 36 | public static ActiveXComponent sC; 37 | 38 | public static DispatchEvents de = null; 39 | 40 | public static DispatchProxy sCon = null; 41 | 42 | @Test 43 | public void testActiveXSTA() { 44 | try { 45 | ComThread.InitSTA(); 46 | ScriptTest2ActiveXSTA script = new ScriptTest2ActiveXSTA(); 47 | try { 48 | Thread.sleep(1000); 49 | } catch (InterruptedException ie) { 50 | // should we get this? 51 | } 52 | 53 | // get a thread-local Dispatch from sCon 54 | ActiveXComponent sc = new ActiveXComponent(sCon.toDispatch()); 55 | 56 | // call a method on the thread-local Dispatch obtained 57 | // from the DispatchProxy. If you try to make the same 58 | // method call on the sControl object - you will get a 59 | // ComException. 60 | String scriptCommand = getSampleVPScriptForEval(); 61 | Variant result = sc.invoke("Eval", scriptCommand); 62 | System.out.println("eval(" + scriptCommand + ") = " + result); 63 | script.quit(); 64 | System.out.println("called quit"); 65 | } catch (ComException e) { 66 | e.printStackTrace(); 67 | fail("blew up with Com Exception " + e); 68 | } finally { 69 | Integer I = null; 70 | for (int i = 1; i < 1000000; i++) { 71 | I = new Integer(i); 72 | } 73 | System.out.println(I); 74 | ComThread.Release(); 75 | } 76 | } 77 | 78 | public class ScriptTest2ActiveXSTA extends STA { 79 | 80 | public boolean OnInit() { 81 | try { 82 | System.out.println("OnInit"); 83 | System.out.println(Thread.currentThread()); 84 | String lang = "VBScript"; 85 | sC = new ActiveXComponent("ScriptControl"); 86 | 87 | // sCon can be called from another thread 88 | sCon = new DispatchProxy(sC); 89 | 90 | sC.setProperty("Language", lang); 91 | ScriptTestErrEvents te = new ScriptTestErrEvents(); 92 | de = new DispatchEvents(sC, te); 93 | return true; 94 | } catch (Exception e) { 95 | e.printStackTrace(); 96 | return false; 97 | } 98 | } 99 | 100 | public void OnQuit() { 101 | System.out.println("OnQuit"); 102 | } 103 | 104 | } 105 | 106 | } -------------------------------------------------------------------------------- /src/test/com/jacob/test/vbscript/ScriptTest3.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.vbscript; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.activeX.ActiveXComponent; 6 | import com.jacob.com.ComException; 7 | import com.jacob.com.ComThread; 8 | import com.jacob.com.Dispatch; 9 | import com.jacob.com.DispatchEvents; 10 | import com.jacob.com.Variant; 11 | import com.jacob.test.BaseTestCase; 12 | 13 | /** 14 | * Here we create the ScriptControl component in a separate MTA thread and then 15 | * call the Eval method from the main thread. The main thread must also be an 16 | * MTA thread. If you try to create it as an STA then you will not be able to 17 | * make calls into a component running in another thread. 18 | *

19 | * May need to run with some command line options (including from inside 20 | * Eclipse). Look in the docs area at the Jacob usage document for command line 21 | * options. 22 | */ 23 | public class ScriptTest3 extends BaseTestCase { 24 | 25 | public static ActiveXComponent sC; 26 | 27 | public static DispatchEvents de = null; 28 | 29 | public static Dispatch sControl = null; 30 | 31 | public static boolean quit = false; 32 | 33 | @Test 34 | public void testScript() { 35 | try { 36 | ComThread.InitMTA(); 37 | ScriptTest3Inner script = new ScriptTest3Inner(); 38 | script.start(); 39 | try { 40 | Thread.sleep(1000); 41 | } catch (InterruptedException ie) { 42 | // should we get this? 43 | } 44 | 45 | Variant result = Dispatch.call(sControl, "Eval", 46 | getSampleVPScriptForEval()); 47 | System.out.println("eval(" + getSampleVPScriptForEval() + ") = " 48 | + result); 49 | System.out.println("setting quit"); 50 | ScriptTest3.quit = true; 51 | } catch (ComException e) { 52 | e.printStackTrace(); 53 | fail("Caught excpetion running script with MTA"); 54 | } finally { 55 | System.out.println("main done"); 56 | ComThread.Release(); 57 | } 58 | } 59 | 60 | class ScriptTest3Inner extends Thread { 61 | public void run() { 62 | try { 63 | ComThread.InitMTA(); 64 | System.out.println("OnInit"); 65 | String lang = "VBScript"; 66 | sC = new ActiveXComponent("ScriptControl"); 67 | sControl = sC.getObject(); 68 | Dispatch.put(sControl, "Language", lang); 69 | ScriptTestErrEvents te = new ScriptTestErrEvents(); 70 | de = new DispatchEvents(sControl, te); 71 | System.out.println("sControl=" + sControl); 72 | while (!quit) { 73 | sleep(100); 74 | } 75 | ComThread.Release(); 76 | } catch (Exception e) { 77 | e.printStackTrace(); 78 | } finally { 79 | System.out.println("worker thread exits"); 80 | } 81 | } 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/test/com/jacob/test/vbscript/ScriptTest3ActiveX.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.vbscript; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.activeX.ActiveXComponent; 6 | import com.jacob.com.ComException; 7 | import com.jacob.com.ComThread; 8 | import com.jacob.com.DispatchEvents; 9 | import com.jacob.com.Variant; 10 | import com.jacob.test.BaseTestCase; 11 | 12 | /** 13 | * Here we create the ScriptControl component in a separate MTA thread and then 14 | * call the Eval method from the main thread. The main thread must also be an 15 | * MTA thread. If you try to create it as an STA then you will not be able to 16 | * make calls into a component running in another thread. 17 | *

18 | * May need to run with some command line options (including from inside 19 | * Eclipse). Look in the docs area at the Jacob usage document for command line 20 | * options. 21 | */ 22 | public class ScriptTest3ActiveX extends BaseTestCase { 23 | public static ActiveXComponent sC; 24 | 25 | public static DispatchEvents de = null; 26 | 27 | public static boolean quit = false; 28 | 29 | @Test 30 | public void testYetAnotherScriptTest() { 31 | try { 32 | ComThread.InitMTA(); 33 | ScriptTest3ActiveXInner script = new ScriptTest3ActiveXInner(); 34 | script.start(); 35 | try { 36 | Thread.sleep(1000); 37 | } catch (InterruptedException ie) { 38 | // should we get this? 39 | } 40 | 41 | Variant result = sC.invoke("Eval", getSampleVPScriptForEval()); 42 | System.out.println("eval(" + getSampleVPScriptForEval() + ") = " 43 | + result); 44 | System.out.println("setting quit"); 45 | ScriptTest3ActiveX.quit = true; 46 | } catch (ComException e) { 47 | e.printStackTrace(); 48 | fail("Caught ComException " + e); 49 | } finally { 50 | System.out.println("main done"); 51 | ComThread.Release(); 52 | } 53 | } 54 | 55 | public class ScriptTest3ActiveXInner extends Thread { 56 | public void run() { 57 | try { 58 | ComThread.InitMTA(); 59 | System.out.println("OnInit"); 60 | String lang = "VBScript"; 61 | sC = new ActiveXComponent("ScriptControl"); 62 | sC.setProperty("Language", lang); 63 | ScriptTestErrEvents te = new ScriptTestErrEvents(); 64 | de = new DispatchEvents(sC, te); 65 | System.out.println("sControl=" + sC); 66 | while (!quit) { 67 | sleep(100); 68 | } 69 | ComThread.Release(); 70 | } catch (Exception e) { 71 | e.printStackTrace(); 72 | } finally { 73 | System.out.println("worker thread exits"); 74 | } 75 | } 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/test/com/jacob/test/vbscript/ScriptTestActiveX.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.vbscript; 2 | 3 | import org.junit.Test; 4 | 5 | import com.jacob.activeX.ActiveXComponent; 6 | import com.jacob.com.ComException; 7 | import com.jacob.com.ComThread; 8 | import com.jacob.com.DispatchEvents; 9 | import com.jacob.com.Variant; 10 | import com.jacob.test.BaseTestCase; 11 | 12 | /** 13 | * In this case the component is created and used in the same thread and it's an 14 | * Apartment Threaded component, so we call InitSTA. 15 | *

16 | * May need to run with some command line options (including from inside 17 | * Eclipse). Look in the docs area at the Jacob usage document for command line 18 | * options. 19 | */ 20 | public class ScriptTestActiveX extends BaseTestCase { 21 | 22 | @Test 23 | public void testActiveXScript() { 24 | ComThread.InitSTA(true); 25 | DispatchEvents de = null; 26 | 27 | try { 28 | String lang = "VBScript"; 29 | ActiveXComponent sC = new ActiveXComponent("ScriptControl"); 30 | sC.setProperty("Language", lang); 31 | ScriptTestErrEvents te = new ScriptTestErrEvents(); 32 | de = new DispatchEvents(sC, te); 33 | if (de == null) { 34 | System.out 35 | .println("null returned when trying to create DispatchEvents"); 36 | } 37 | Variant result; 38 | result = sC.invoke("Eval", getSampleVPScriptForEval()); 39 | // call it twice to see the objects reused 40 | result = sC.invoke("Eval", getSampleVPScriptForEval()); 41 | // call it 3 times to see the objects reused 42 | result = sC.invoke("Eval", getSampleVPScriptForEval()); 43 | System.out.println("eval(" + getSampleVPScriptForEval() + ") = " 44 | + result); 45 | } catch (ComException e) { 46 | e.printStackTrace(); 47 | } finally { 48 | Integer I = null; 49 | for (int i = 1; i < 1000000; i++) { 50 | I = new Integer(i); 51 | } 52 | System.out.println(I); 53 | ComThread.Release(); 54 | ComThread.quitMainSTA(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/com/jacob/test/vbscript/ScriptTestErrEvents.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.vbscript; 2 | 3 | import com.jacob.com.Variant; 4 | 5 | /** 6 | * Extracted from ScriptTest so everyone can see this Made a test solely because 7 | * it made the ant test easier 8 | */ 9 | public class ScriptTestErrEvents { 10 | 11 | public void Error(Variant[] args) { 12 | System.out.println("java callback for error!"); 13 | } 14 | 15 | public void Timeout(Variant[] args) { 16 | System.out.println("java callback for error!"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/com/jacob/test/windowsmedia/WMPlayer.java: -------------------------------------------------------------------------------- 1 | package com.jacob.test.windowsmedia; 2 | 3 | /** 4 | * partial test program from the sourceforge bug report 1453161 5 | * that says you get a random "can't map name to dispid" when 6 | * getting the URL from the player 7 | *

8 | * this doesn't actually play for some reason. It always says the length is 0. 9 | *

10 | * May need to run with some command line options (including from inside Eclipse). 11 | * Look in the docs area at the Jacob usage document for command line options. 12 | *

13 | */ 14 | import java.io.File; 15 | 16 | import org.junit.Test; 17 | 18 | import com.jacob.activeX.ActiveXComponent; 19 | import com.jacob.com.Dispatch; 20 | import com.jacob.com.Variant; 21 | import com.jacob.test.BaseTestCase; 22 | 23 | public class WMPlayer extends BaseTestCase { 24 | 25 | /** 26 | * This should demo the media player but it doesn't 27 | */ 28 | @Test 29 | public void testOpenWMPlayer() { 30 | // this file exists in windows 7 installations 31 | File file = new File( 32 | "C:/Windows/winsxs/x86_microsoft-windows-videosamples_31bf3856ad364e35_6.1.7600.16385_none_f583837f77a63ec7"); 33 | String filePath = file.getAbsolutePath(); 34 | String microsoftTestURL = filePath; 35 | // use these instead if not on windows 7 36 | // "http://support.microsoft.com/support/mediaplayer/wmptest/samples/new/mediaexample.wma"; 37 | // "http://support.microsoft.com/support/mediaplayer/wmptest/samples/new/mediaexample.wmv"; 38 | ActiveXComponent wmp = null; 39 | // could use WMPlayer.OCX alias also 40 | wmp = new ActiveXComponent( 41 | "CLSID:{6BF52A52-394A-11D3-B153-00C04F79FAA6}");// ("WMPlayer.OCX"); 42 | 43 | wmp.setProperty("URL", microsoftTestURL); 44 | assertEquals(wmp.getProperty("URL").toString(), microsoftTestURL); 45 | 46 | // alternative way to get the controls 47 | Dispatch controls = Dispatch.get(wmp, "controls").toDispatch(); 48 | Dispatch.call(controls, "Play"); 49 | // the sourceforge posting didn't post all the code so this is all we 50 | // have we need some other information on how to set the document 51 | // so that we have a url to open 52 | 53 | // pause to let it play a second or two 54 | try { 55 | Thread.sleep(1500); 56 | } catch (InterruptedException e) { 57 | System.out.println("Thread interrupted"); 58 | } 59 | for (int i = 0; i < 1000; i++) { 60 | // Get media object 61 | Dispatch vMedObj = wmp.getProperty("currentMedia").toDispatch(); 62 | // Get duration of media object 63 | Variant vdur = Dispatch.call(vMedObj, "duration"); 64 | // why is this always 0? 65 | // System.out.println(microsoftTestURL + " length is " 66 | // + vdur.getDouble()); 67 | // System.out.println("the wmp url is " 68 | // + wmp.getProperty("URL").toString()); 69 | } 70 | 71 | } 72 | } 73 | --------------------------------------------------------------------------------