Converting a Java Applet to COM

I can make FormatNumbers available to other applications through COM without making any changes to the source code; Developer Studio provides a wizard that automatically generates the required interface definitions, registration entries, and identifiers. Figure 7-1 shows the FormatTest application as it appears when it is loaded into the development environment, from which the ActiveX Component For Java Wizard is started.

Figure 7-1. FormatTest in Developer Studio.

From the Tools menu, I select the ActiveX Wizard For Java item. The Input Files dialog box, shown in Figure 7-2, will appear. In the first text box, I have filled in the name of the class that I want to expose. Note that this should be the name of a .class object file, not a .java source file; I compiled my Java code before invoking the wizard.

The next field in this dialog box allows me to decide whether to use an existing Interface Definition Language (IDL) file or to have the wizard generate one for me. As I discussed in Chapter 6, an IDL file describes the interfaces exposed by a COM component. For complex classes that export several interfaces, I usually ask the wizard to generate an initial IDL file that I later customize for my own purposes. For this example, I’ll have the wizard create a new IDL file based on the methods exported by my FormatNumbers class.

Figure 7-2. The ActiveX Component Wizard Input Files dialog box.

The next ActiveX Component Wizard dialog box is shown in Figure 7-3. In this box, I need to determine the CLSID for my ActiveX class; if I had already created a unique identifier, I could enter it in the provided text field; otherwise (and in most cases), I want the wizard to generate a CLSID for me. This value is guaranteed to be unique for my class; for each subsequent release or version of my component, I’ll use a new CLSID to differentiate the new code from the old.

At the bottom of the CLSID dialog box is a pair of radio buttons that tell the wizard whether or not I want it to automatically register the new ActiveX component. In this case, I want the wizard to perform the registration for me.

Figure 7-3. The ActiveX Component Wizard CLSID dialog box.

The next dialog box, shown in Figure 7-4, asks for information about the type of interface to be supported by the new ActiveX component. Remember, a COM object can support either a dispinterface or a dual interface (for indirect access); the first pair of radio buttons allows me to select one of these options. FormatNumbers is a pretty simple class, with only eight exported methods; I decided to have the wizard construct a dispinterface interface.

The second set of radio buttons lets me create a type library from the IDL file; I’ve done this for FormatNumbers. A type library provides information about the types, methods, and interfaces exposed by a COM object; in most cases, you’ll want the wizard to generate a .tlb file for you.

Figure 7-4. The ActiveX Component Wizard Interfaces dialog box.

The ActiveX Component Wizard doesn’t do everything for me, however. The next dialog box, shown in Figure 7-5, lists the steps I must take to complete the conversion process.

Figure 7-5. The ActiveX Component Wizard Additional Steps dialog box.

 The first item is a list box containing a set of statements that should replace the class statement in my source file. For FormatNumbers, the wizard used the information from the previous dialog boxes to generate a new import statement, an additional implements clause for the FormatNumbers class definition, and an exposed constant containing the CLSID for the new COM component. I’ll do the following to add this code to my program.

  1. Select the code in the list box.

  2. Copy the code to the clipboard (using Ctrl-Ins or Ctrl-C).

  3. Move to the window that contains the Java source code for my class (in this case, FormatNumbers.java).

  4. Insert the text from the clipboard in place of the public class FormatNumbers header.

  5. Save the source file with the new code.

  6. Return to the wizard’s dialog box.

Figure 7-6 shows how the FormatNumbers class will look after the class header has been changed.

Figure 7-6. FormatNumbers with the new class header.

The next step is to verify that the component’s output will be stored in the appropriate directory, usually C:\Windows\java\lib. You can set the output directory in the Project Settings window, as shown in Figure 7-7 on the following page.

Figure 7-7. The build settings window for FormatTest.

Finally, I will recompile my FormatNumbers Java class by making it the current text window and pressing Ctrl-F7. I could also have done this by choosing the Compile item from the Build menu or by clicking the Compile button on the toolbar.

In Figure 7-8 (on page 176), I’ve maximized the output window in Developer Studio so that you can see the output from the various compilers and tools. After it has compiled the Java source file, the MIDL (Microsoft IDL) compiler is invoked for the IDL file I specified earlier. In this example, I asked the ActiveX Wizard to generate an IDL file for me; it creates the following text file.

[
    uuid(30b460da-c1ad-11d0-8c48-00c04fc29cec),
    helpstring("FormatNumbersLib Type Library"),
    version(1.0)
]
library FormatNumbersLib
{
    importlib("stdole32.tlb");

    [
        uuid(30b460d9-c1ad-11d0-8c48-00c04fc29cec),
        helpstring("IFormatNumbers Interface")
    ]
    dispinterface IFormatNumbers
    {
        properties:
        methods:
        [ helpstring("setSeparatorSymbol Method"), id(1) ]
        void setSeparatorSymbol([in] char p1);

        [ helpstring("getSeparatorSymbol Method"), id(2) ]
        char getSeparatorSymbol();

        [ helpstring("setGroupLen Method"), id(3) ]
        void setGroupLen([in] long p1);

        [ helpstring("getGroupLen Method"), id(4) ]
        long getGroupLen();

        [ helpstring("formatComma Method"), id(5) ]
        BSTR formatComma([in] long p1);

        [ helpstring("setCurrencySymbol Method"), id(6) ]
        void setCurrencySymbol([in] char p1);

        [ helpstring("getCurrencySymbol Method"), id(7) ]
        char getCurrencySymbol();

        [ helpstring("formatText Method"), id(8) ]
        BSTR formatText([in] long p1);

    }

    [
        uuid(30b460d8-c1ad-11d0-8c48-00c04fc29cec),
        helpstring("CFormatNumbers Object")
    ]
    coclass CFormatNumbers
    {
        [ default ]
        dispinterface IFormatNumbers;
    };

};

When the MIDL compiler is finished, Developer Studio runs the Java Type Library Wizard to create a .tlb file from your interface definitions. The last output line tells you that a file named summary.txt has been generated to describe the interfaces for your class. Double-click on this line to see a Java-like text file that lists the interfaces and exposed methods for the new COM class.

Figure 7-8. The output messages generated by the ActiveX Component Wizard.

© 1997 by Scott Ladd. All rights reserved.