This part of the userguide, covers how to use Jawin when calling
		scriptable COM interfaces, ie. COM interfaces implementing the 
		IDispatch interface. The information herein covers the
		"low-level" code, close to Jawin. This is the form of code the
		Jawin Type Browser
		generates - this generated code should be used instead of manually 
		writing this "low-level" code. If the Jawin Type Browser is not able
		to generate complete stub-code for a COM interface, the guidelines in this
		document should be followed for manually writing the stub-code.
	
The COM dictionary is full of cryptic terms and abbrevations that one must know a minimum of to use Jawin succesfully. If terms such as GUID, CLSID, IID or ProgID are only vague known to you, please take the time to read the quick overview of these terms in section 1 in the Userguide - Calling a VTable Based COM Interface document.
		As shown in the PowerPoint demo from the 
		introduction to Jawin,
		using the IDispatch interface on any scriptable
		COM object is relatively straightforward:
	
DispatchPtr object, using either the
		ProgId or the CLSID for the relevant COM
		object.get() and getN() methods in
				DispatchPtr.put() and putN() methods in
				DispatchPtr.invoke()
				and invokeN() methods in DispatchPtr.
		The following subsections are dedicated to how to use each of these
		three groups of methods on the DispathPtr-class.
	
Note that COM requires that all threads calling a COM object must initialize the COM library. This is done by calling:
		
			Ole32.CoInitialize();
		
	
After a thread is finished with all COM calls, it should call:
		
			Ole32.CoUninitialize();
		
	
Microsoft MSDN documents the details of these two methods; CoInitializeEx and CoUninitialize.
It should be noted that COM has a special thread model. So if using COM objects in multithreaded applications, you unfortunately have to know at least the basic of this. So please see the section on Threading Issues if using COM objects from several threads.
		When finished with the dispatch interface object, the close()
		method must be called to let COM decrease the reference count for
		the COM-object, and ultimately destroy the object. This call must happen
		on the same thread that created the interface object. And even though
		the DispatchPtr contains a finalize-method that 
		tries to release the resources if close() was not
		explicitely called, this can not be relied on, since Java neither
		guarentees that finalize() will ever be called, nor is
		it guarenteed from which thread it will be called.
	
		The getters are straightforward, as the caller only needs to 
		specify the property to retrieve (and additional index(es) for
		identifying the exact property value). DispatchPtr
		offers three methods for this (please refer to the javadoc
		for additional information about the specific parameters).
	
		
			public Object get(String prop) throws COMException;
	
			public Object get(String prop, Object index) throws COMException;
			public Object getN(String prop, Object[] indexes) throws COMException;
		
		After invoking one of these methods the caller only needs to cast the
		result to the correct type (and retrieve the simple type if suitable).
		The javadoc for Variant.ReadObject() specifies how
		native Variant types are converted into Java types - for most
		developers there should be no surprises in conversion (ie. native
		int is converted to java.lang.Integer, etc.).
	
To set a property value should be just as straightforward as getting a property value. Again there are three groups of setter-methods, for setting properties taking different numbers of indexes for identifying the property.
		
			public void put(String prop, Object val) throws COMException;
	
			public void put(String prop, Object index, Object val) throws COMException;
			public void putN(String prop, Object[] indexes, Object val) throws COMException;
		
Because of Java's support for overloaded methods a number of shortcut methods also exists for setting properties of simple types, eg. the following method for setting a 4-byte signed integer (a socalled VT_I4):
		
			public void put(String prop, int val) throws COMException;
		
	
		If you need detailed control of how Jawin converts Java types into native 
		Variants the javadoc for Variant.WriteObject() must be 
		consulted. But please notice that the IDispatch coercion
		mechanism handles scenarios where the VT_TYPE of a parameter is a
		not a 100% fit to a method signature or property. Therefore there
		should not be any problems by setting eg. a property requering
		unsigned int's with either a long or an int.
	
If you got this far, you can probably guess that invoking methods on the dispatch interface is mostly just a combination of getting and setting properties, that is passing some values to a method as java Objects, and using any return value as another java Object.
		Again the javadoc for respectively Variant.WriteObject()
		and Variant.ReadObject() should be consulted for details
		about marshalling and unmarshalling of parameters and return values.
	
		There is one special case that needs a few additional words, the 
		handling of socalled [out] parameters. [out]
		parameters are usually used when a method returns several values
		(ie. the return value is "not enough"). An example of such a method
		could be:
	
		
			int doSomething([in] int inValue, [out] int outValue);
		
	
		This method "returns" two values: both the usual return value and
		the value in the outValue parameter.
	
		To use such a method from Jawin, one have to use the 
		org.jawin.Variant.ByrefHolder class (the name originates
		from the term passing by reference instead of the usual by
		value). The example below shows the usage of a
		ByrefHolder wrapping object. To call the above defined
		doSomething method, the Java code should be like:
	
		
			..
	
			// the usual in value
			Integer inValue = new Integer(42);
			// wrap the out value in a ByrefHolder
			Variant.ByrefHolder outValueRef = new Variant.ByrefHolder(new Integer(0));
			
			// call the method
			Integer result = (Integer)dispatchPtr.invoke("doSomething", inValue, outValueRef);
			
			// unwrap the outValue
			Integer outValue = (Integer)outValueRef.getRef();
			..
		
		It should be noted in the above code, that one has to pass an "empty"
		object of the correct type to the ByrefHolder constructor.
		This is necessary to get the byref value marshalled into the correct
		VT_TYPE (in the example above our "empty" value, is the
		new Integer(0)).
	
		When working with arrays in a dispatch interface, one has to know in
		some detail how the different java-arrays get marshalled to native
		Variants. Especially it is important to understand the difference
		between arrays of simple types (like int[]) and arrays
		of objects (like Integer[]). The rules are as follows:
	
| Java Array | Variant Type | Comments | 
|---|---|---|
| String[] | VT_ARRAY | VT_BSTR | Special case of the below array of Java objects. | 
| Object[] | VT_ARRAY | VT_VARIANT | Each of the individual objects are then marshalled as an ordinary
			Variant, eg. a Java array of Integer-objects are 
			marshalled asVT_ARRAY | VT_VARIANT (VT_UI4). One
			can pass arrays of different Variant types, eg. the following is
			possiblenew Object[]{ "some string" , new Integer(42) ,
			Boolean.TRUE } | 
| simple type array (eg. int[]) | VT_ARRAY |
			VT for simple type | Examples: int[] -> VT_ARRAY | VT_UI4double[] -> VT_ARRAY | VT_R8 | 
| DispatchPtr[](or subclass) | VT_ARRAY | VT_DISPATCH | Another special case of array of Java objects. | 
| UnknownPtr[](or subclass) | VT_ARRAY | VT_UNKNOWN | Another special case of array of Java objects. | 
		The COM error model uses socalled HRESULT's as return values
		to indicate failure of a call. Jawin maps this into the Java
		Exception hierarchy by throwing a 
		org.jawin.COMException on failure. This means that
		the user can program in standard Java-style, ie. catching exceptions
		and not having to worry about checking return HRESULT's.
	
		Section 5 in the Jawin Architecture document contains
		some additional information about the conversion of HRESULT's into
		COMExceptions.
	
If using COM references in multithreaded applications, you must make yourself comportable with how Jawin handles the threading issues that are present in COM. This is presented in section 6 in the Jawin Architecture document.
Additional resources when working with scriptable COM objects from Jawin
| Copyright (c) 2000-2005, The Jawin Project - LICENSE |  | 
| This documentation was written for version: 2.0, alpha 1 of Jawin. | |
| $Id: jawinuserguide_dispatch.html,v 1.6 2004/08/01 21:34:26 arosii_moa Exp $ |