Java and COM Automation 
by Kenneth Bandes
            

Listing One
javareg /register /class:autoXTest /clsid:"{735640F0-3B59-11D1-B5B9-98596A000000}" /typelib:autoXTest.tlb /progid:"autoXTest.Main" /codebase:"g:\projects\autoX"


Listing Two
[
    object,
    uuid(4f9dfa91-32ef-11d1-b5ac-9e4a44000000), dual,
    pointer_default(unique), helpstring("Application Interface")
]
interface Application : IDispatch
{
    /* for Application, this just returns pointer to self */
    [
        propget, helpstring("Application property")
    ]
    HRESULT Application([out,retval] Application** val);

    /* Parent, i.e. containing object for Application, returns pointer 
                                                               to itself */
    [
        propget, helpstring("Parent property")
    ]
    HRESULT Parent([out,retval] Application** val);

    /* name of the application */
    [
        propget, id(DISPID_VALUE), helpstring("Application Name")
    ]
    HRESULT Name([out,retval] BSTR* val);

    /* the collection of open AddressBooks */
    [
        propget, helpstring("AddressBooks property")
    ]
    HRESULT AddressBooks([out,retval] AddressBooks** val);
}

Listing Three 
// Auto-generated using JActiveX.EXE 4.79.2207
//   (JActiveX AddressBookLib.tlb)
// WARNING: Do not remove the comments that include "@com" directives.
// This source file must be compiled by a @com-aware compiler.
// If you are using the Microsoft Visual J++ compiler, you must use
// version 1.02.3920 or later. Previous versions will not issue an error
// but will not generate COM-enabled class files.

package addressbooklib;

import com.ms.com.*;
import com.ms.com.IUnknown;
import com.ms.com.Variant;

// Dual interface Application
/** @com.interface(iid=4F9DFA91-32EF-11D1-B5AC-9E4A44000000, 
                                              thread=AUTO, type=DUAL) */
public interface Application extends IUnknown
{
  /** @com.method(vtoffset=4, dispid=1610743808, type=PROPGET, 
                                   name="Application", addFlagsVtable=4)
      @com.parameters([iid=4F9DFA91-32EF-11D1-B5AC-9E4A44000000,
                                        thread=AUTO,type=DISPATCH] return) */
  public addressbooklib.Application getApplication();

  /** @com.method(vtoffset=5, dispid=1610743809, type=PROPGET, name="Parent", 
                                                 addFlagsVtable=4)
      @com.parameters([iid=4F9DFA91-32EF-11D1-B5AC-9E4A44000000,thread=AUTO,
                                             type=DISPATCH] return) */
  public addressbooklib.Application getParent();

  /** @com.method(vtoffset=6, dispid=0, type=PROPGET, name="Name", 
                                                        addFlagsVtable=4)
      @com.parameters([type=STRING] return) */
  public String getName();

  /** @com.method(vtoffset=7, dispid=1610743811, type=PROPGET, 
                                      name="AddressBooks", addFlagsVtable=4)
      @com.parameters([iid=4F9DFA96-32EF-11D1-B5AC-9E4A44000000,
                                        thread=AUTO,type=DISPATCH] return) */
  public addressbooklib.AddressBooks getAddressBooks();

  public static final com.ms.com._Guid iid = 
       new com.ms.com._Guid((int)0x4f9dfa91, (short)0x32ef, (short)0x11d1, 
       (byte)0xb5, (byte)0xac, (byte)0x9e, (byte)0x4a, (byte)0x44, (byte)0x0, 
       (byte)0x0, (byte)0x0);
}


Listing Four
    [
        uuid(4f9dfa95-32ef-11d1-b5ac-9e4a44000000),
        appobject,  // the Application object
        helpstring("The Application Object for the AddressBook API")
    ]
    coclass CApplication
    {
        interface Application;
    };


Listing Five
[
    object,
    uuid(4f9dfa92-32ef-11d1-b5ac-9e4a44000000),
    dual,
    pointer_default(unique),
    helpstring("AddressBook Interface")
]
interface AddressBook : IDispatch
{
    [
        propget, helpstring("Application property")
    ]
    HRESULT Application([out,retval] Application** val);

    [
        propget, helpstring("Parent property")
    ]
    HRESULT Parent([out,retval] AddressBooks** val);

    [
        propget, helpstring("The file name with path for this AddressBook")
    ]
    HRESULT FullName([out,retval] BSTR* val);

    [
      propget, helpstring("The file name (without path) for this AddressBook")
    ]
    HRESULT Name([out,retval] BSTR* val);

    [
      propget, helpstring("The path (without file name) for this AddressBook")
    ]
    HRESULT Path([out,retval] BSTR* val);

    [
        propget, 
        helpstring("Whether the file has been saved since the last changes")
    ]
    HRESULT Saved([out,retval] VARIANT_BOOL *val);

    [
        helpstring("close the Address Book")
    ]
    HRESULT Close();

    [
        helpstring("Save changes to Address Book")
    ]
    HRESULT Save();

    [
        propget, helpstring("Returns number of entries.")
    ]
    HRESULT Count([out, retval] long* retval);

    [
        propget, restricted, id(DISPID_NEWENUM),
        helpstring("returns an enumerator for the collection.")
    ]
    HRESULT _NewEnum([out, retval] IUnknown** ret); 

    [
        helpstring("Add a new Address entry.")
    ]
    HRESULT Add([in] BSTR name, [out,retval] Address** ret);

    [
        id(DISPID_VALUE), 
        helpstring("Given a name, returns the Address entry.")
    ]
    HRESULT Item([in] BSTR name, [out, retval] Address** ret);

    [
        helpstring("Remove an Address from the collection.")
    ]
    HRESULT Remove([in] BSTR name);

    [
        propget, helpstring("returns an enumerator for the collection.")
    ]
    HRESULT Enum([out, retval] DIEnum** ret);   

}

Listing Six
    public void Next(int n, Variant v[], int x[])
    {
        int i;
        for(i = 0; i < n && enum.hasMoreElements(); ++i)
        {
            Variant var = new Variant(enum.nextElement());
            v[i] = var;
        }
        if(x != null)
            x[0] = i;
        if(i < n)
            /* returns S_FALSE status, indicating end of collection reached */
            throw new ComSuccessException();
    }


Listing Seven
    // get a COM enumeration object for this collection
    private AutoEnum getAutoEnum()
    {
        /* use an anonymous class to implement the Enumerable
         * interface required by AutoEnum's constructor */
        return new AutoEnum(new Enumerable() {
            // get an Enumeration on the collection
            public Enumeration elements()
            {
                return entries.elements();
            }
        });
    }


Listing Eight

    public void Skip(int n)
    {
        while((n-- > 0) && enum.hasMoreElements())
            enum.nextElement();
        if(n > 0)
            // returns S_FALSE status, indicating end of collection reached
            throw new ComSuccessException();
    }


Listing Nine

    public IEnumVariant Clone()
    {
        throw new ComFailException( 
                         StdErrors.E_NOTIMPL, "Clone method not supported");
    }


Listing Ten
    enum StdErrors
    {
        [helpstring("Unexpected failure")]
        E_UNEXPECTED = 0x8000FFFF,

        [helpstring("Not implemented")]
        E_NOTIMPL = 0x80004001,

        [helpstring("Ran out of memory")]
        E_OUTOFMEMORY = 0x8007000E,

        // etc.
    };


Listing Eleven
    enum Errors
    {
        E_FIRST = 0x80040200,
    
        [helpstring("Index not valid for collection")]
        E_OUTOFBOUNDS,

        [helpstring("Specified Item not Found")]
        E_ITEMNOTFOUND,

        // etc.
    };


Listing Twelve
    public Object NextElement()
    {
        if(enum.hasMoreElements())
            return enum.nextElement();
        else
            throw new ComFailException(
                        Errors.E_OUTOFBOUNDS, 
                        "Attempt to Retrieve after last element");
    }


Listing Thirteen

REM reg.cmd
REM Register the Applicationimpl class as a COM object
REM /register means register the class
REM /class specifies which class
REM /clsid specifies the class id, which is the UUID of the coclass
REM /progid specifies a human-readable alias for the class id
javareg /register /class:Applicationimpl /clsid:"{4f9dfa95-32ef-11d1-b5ac-9e4a44000000}" /progid:"AddressBook.Application"





5


