HOME> SWT

このドキュメントはEclipsetechnical articlesにある ActiveX Support In SWT を私、Takayukiが日本語に翻訳したものです。誤訳がある場合はtakayuki at users.sourceforge.jpまでお願いします。


Copyright © 2001 Object Technology International, Inc.

Eclipse Corner Article

SWTのActiveXサポート
ActiveX Support In SWT

どのようにしてOLEドキュメントやActiveXコントロールをEclipseプラグインに含めるか

How do I include an OLE Document or ActiveX Control in my Eclipse plugin?

概要
Word、Excel、PowerPointのようなOLEドキュメントとInternet Explorerのような ActiveXコントロールはMicrosoft® Windows®プラットフォームで動作するほかのアプリケーションに 埋め込み可能なCOMオブジェクトです。 この記事ではSWTを使ったアプリケーションにOLEドキュメントとActiveXコントロールを 統合する概要を提供します。

Summary
OLE Documents, such as Word, Excel or PowerPoint, and ActiveX Controls such as Internet Explorer are COM objects that can be embedded into other applications running on a Microsoft® Windows® platform. This article provides an overview of integrating OLE Documents and ActiveX Controls into an application using SWT.

By Veronika Irvine, OTI
March 22, 2001


SWTアプリケーションにOLEオブジェクトを埋め込む
Embedding an OLE Object in your SWT Application

OLEオブジェクトはSWTウィジェットに含めることができます。 そこから、ユーザーとの相互作用でアクティベートしたりデアクティベートし、 特性しだいでアプリケーションによって操作されます。 たとえば、編集されたデータと状態は回収されるか保存されます。 オブジェクトが不要になると破棄することができます。

OLE Objects can be contained in SWT widgets. From there, they can be activated and deactivated for user interaction, and manipulated by the application according to their specification. For example, edited data and state can be retrieved or saved. If the object is no longer required, it can be disposed.

OLEオブジェクトの生成
Create the OLE Object

OLEドキュメントやActiveXコントロールはコンテナに挿入されることによってアプリケーションに追加されます。 コンテナは2つの部分から構成されています。

An OLE Document or ActiveX Control is added to an application by inserting it into a Container. The Container is made up of two parts:

  1. OleFrameオブジェクトはサイズ、メニュー管理、ウィンドウ位置を処理します。
  2. OleClientSite(OLEドキュメント用)またはOleControlSite(ActiveXコントロール用)は特定のOLEオブジェクトと相互的に処理します。
  1. The OleFrame object handles sizing, menu management and window placement.
  2. The OleClientSite (for OLE Documents) or OleControlSite (for ActiveX Controls) handles interactions with a specific OLE Object

OLEオブジェクトを埋め込む最初のステップはOleFrameを生成することです。

The first step in embedding an OLE Object is to create the OleFrame:

    Display display = new Display();
    Shell shell = new Shell(display);
    OleFrame frame = new OleFrame(shell, SWT.NONE);

アクティベートされたとき、OLEドキュメントはアプリケーションメニューバーのトップに自身のメニューバーを表示します。 アプリケーションはOleFrameを通して次のようにしてOLEドキュメントのメニューバーにメニューを追加することができます。

When activated, an OLE Document displays its own menu bar over top of the application's menu bar. The application can contribute menus to the OLE Document's menu bar through the OleFrame as follows:

    Menu bar = new Menu(shell, SWT.BAR);
    shell.setMenuBar(bar);
    
    MenuItem fileItem1 = new MenuItem(bar, SWT.CASCADE);
    fileItem1.setText("&File_Item_1");
    MenuItem fileItem2 = new MenuItem(bar, SWT.CASCADE);
    fileItem2.setText("&File_Item_2");

    MenuItem containerItem = new MenuItem(bar, SWT.CASCADE);
    containerItem.setText("&Container_Item");

    MenuItem windowItem1 = new MenuItem(bar, SWT.CASCADE);
    windowItem1.setText("&Window_Item_1");
    MenuItem windowItem2 = new MenuItem(bar, SWT.CASCADE);
    windowItem2.setText("&Window_Item_2");

    frame.setFileMenus(new MenuItem[] {fileItem1, fileItem2});
    frame.setContainerMenus(new MenuItem[] {containerItem});
    frame.setWindowMenus(new MenuItem[] {windowItem1, windowItem2});

次のステップはOleClientSiteまたはOleControlSiteを生成することです。 いくつかのCOMオブジェクトはOLEドキュメントとActiveXコントロールの両方として機能します。 OLEドキュメントを埋め込むことはアプリケーション全体を埋め込むことと同じです。 OLEドキュメントはその振る舞いにアクセスするためのツールバーとメニューバーを提供します。 ActiveXコントロールはコンテントパートを提供するだけで、 親アプリケーションはActiveXコントロールのAPIを通して内容の振る舞いを管理しなければなりません。 COMオブジェクトがOLEドキュメントの振る舞いをサポートするかを判断するには IOleDocumentインターフェースを探してください。 COMオブジェクトがActiveXコントロールの振る舞いをサポートするかを判断するには IOleControlインターフェースを探してください。 どちらのオブジェクトをOLEオブジェクトが実装しているかはタイプライブラリを参照してください。

The next step is to create an OleClientSite or an OleControlSite. Some COM objects can function as both an OLE Document and an ActiveX Control. Embedding an OLE Document is equivalent to embedding the entire application. The OLE Document provides its own toolbar and menu bar for accessing its behavior. An ActiveX Control only provides the content part and the parent application must manage the behavior of the content through the API of the ActiveX Control. To determine if a COM object supports the OLE Document behavior, look for the IOleDocument interface. To determine if a COM object supports the ActiveX Control behavior, look for the IOleControl interface. To see which interfaces the OLE Object implements, look at the type library.

OLEドキュメントを埋め込むにはOleClientSiteオブジェクトを生成します。 ActiveXコントロールを埋め込むにはOleControlSiteオブジェクトを生成します。 どちらの場合も親はOleFrameです。 OleClientSiteOleControlSiteを生成したら 関連するOLEドキュメントまたはActiveXコントロールは自動的に生成され、 コンテナサイトと関連付けられます。

To embed an OLE Document, create an OleClientSite object. To embed an ActiveX Control, create an OleControlSite object. The parent in either case is the OleFrame. When you create the OleClientSite or the OleControlSite, the associated OLE Document or ActiveX Control will automatically be created and associated with the container site.

OleClientSiteを生成するには2つの方法があります。

There are two ways to create an OleClientSite:

  1. ProgramIDからOleClientSiteを生成する。 ProgramIDはアプリケーションを識別する文字列です。 例えばWordのProgramIDは"Word.Document"で、ExcelのProgramIDは"Excel.Chart"です。 アプリケーションのProgramIDはWindowsレジストリで見つけることができます。 次のコンストラクタを使い、空白のドキュメント(スタンドアロンアプリケーションから ファイル->新規を選択するのと同様のもの)を作ります。
        OleClientSite clientSite = new OleClientSite(frame, SWT.NONE, "Word.Document");
  2. ストレージファイルからOleClientSiteを生成する。 ストレージファイルはそれを表示できるOLEオブジェクトのタイプについての情報を含む OLEフォーマットのファイルです。 構造化されたストレージフォーマットを持ち、段落フォーマットや辞書、著者/題名/詳細タグのような情報を格納します。 例えば、Wordによって生成された".doc"ファイルはストレージファイルです。 ストレージファイルを与えるとOLEはOLEドキュメントを生成します。
        File file = new File("C:\\OleDocumentation.doc");
        OleClientSite clientSite = new OleClientSite(frame, SWT.NONE, file);
    
  1. Create an OleClientSite from a ProgramID. A ProgramID is a string that identifies the application. For example, the ProgramID for Word is "Word.Document" and the ProgramID for Excel is "Excel.Chart". The ProgramID for an application can be found in the Windows Registry. Using the following constructor, a blank document is created (similar to choosing File->New from a standalone application):
        OleClientSite clientSite = new OleClientSite(frame, SWT.NONE, "Word.Document");
    
  2. Create an OleClientSite from a Storage file. A Storage file is a file with an OLE format that contains information about the type of OLE Object that can view it. It also contains a structured storage format and will store information such as paragraph formats, dictionaries or Author/Title/Description tags. For example, a ".doc" file created by Word is a Storage file. Given a Storage file, OLE will figure out which OLE Document to create.
        File file = new File("C:\\OleDocumentation.doc");
        OleClientSite clientSite = new OleClientSite(frame, SWT.NONE, file);
    

OleControlSiteはActiveXコントロール用にProgramIDから生成されます。 例えば、Internet ExplorerのProgramIDは"Shell.Explorer"です。 Webブラウザは以下のようにしてアプリケーションに埋め込むことができます。

An OleControlSite is created from the ProgramID for the ActiveX Control. For example, the ProgramID for the Internet Explorer is "Shell.Explorer". The web browser can be embedded in an application as follows:

    OleControlSite controlSite = new OleControlSite(frame, SWT.NONE, "Shell.Explorer");

OLEオブジェクトをアクティベートする
Activate the OLE Object

OLEドキュメントやActiveXコントロールがアプリケーション内部で見えるようになる前の最終ステップは OLEオブジェクトをアクティベートすること(よくin-place activationとして参照される)です。 これはOleClientSiteにおいて"doVerb"を呼び出すことで行います。 "doVerb"の文法は次の通りです。

The final step before an OLE Document or ActiveX control becomes visible inside the application is to activate the OLE Object (often referred to as in-place activation). This is done by invoking the "doVerb" action on the OleClientSite or OleControlSite. The "doVerb" syntax is as follows:

    public int doVerb(int verb)

where

詳細 "doVerb": MSDN Library: Windows CE Documentation->Application Development->API Reference->Core ->Interfaces->IOleObject::IUnknown->IOleObject::DoVerb

Further Reading on "doVerb": MSDN Library: Windows CE Documentation->Application Development->API Reference->Core ->Interfaces->IOleObject::IUnknown->IOleObject::DoVerb

OLEドキュメントへの変更の保存
Saving changes to an OLE Document

OLEドキュメントへの変更はストレージファイル化通常のファイルに保存することができます。 以下に記述しているように、ストレージファイルはOLE特有のヘッダに情報を含みます。

The changes made to the OLE Document can be saved to a Storage file or an ordinary file. As described above, a Storage file contains information in the header that is specific to OLE.

Wordのようなアプリケーションはストレージファイルに段落フォーマットや著者の名前や会社名といった 付加的な情報を保存します。Wordドキュメントを通常のファイルに保存するとテキストだけが保存されます。

Applications like Word save additional information in the Storage file such as paragraph formats, Author's name and Company. If you save a Word Document to an ordinary file, only the text will be saved.

いくつかのアプリケーションはOLE特有ではないリソースを編集しますが、 他のアプリケーションが内容を理解できないようになるため それらの内容をストレージファイルに保存できません。 例えば、ビットマップはOLEドキュメントとして埋め込まれたマイクロソフトのペイントで編集できます。 しかしながらビットマップはOLEヘッダを含んでいません。 この場合、内容は通常のファイルとして保存されなければいけません。

Some applications edit resources which are not OLE specific and therefore can not save their contents into a Storage file because then other applications will not understand the contents. For example, a bitmap can be edited with Microsoft's Paint application which can be embedded as an OLE Document. A bitmap, however, has a format that does not include an OLE header. In this case, the contents must be saved to an ordinary file.

ファイルを保存する前に、OleClientSiteのメソッドisDirty()を使って保存の必要性を確認してください。 保存が必要なら、OleClientSiteのメソッドsave(File file, boolean includeOleInfo)を呼び出してください。 boolean includeOleInfoはストレージファイルに保存するときは trueを、通常のファイルに保存するときはfalseを指定してください。

Before saving the file, check that a save is necessary using the method isDirty() on the OleClientSite. If a save is required, invoke the method save(File file, boolean includeOleInfo) on the OleClientSite. The boolean includeOleInfo should be set to true to save to a Storage file and false to save to an ordinary file.

    File file = new File("C:\\OleDocumentation.doc");
    OleClientSite clientSite = new OleClientSite(frame, SWT.NONE, file);

    // ... edit the document ...

    if (clientSite.isDirty()) {
        File tempFile = new File(file.getAbsolutePath() + ".tmp");
        file.renameTo(tempFile);
        if (clientSite.save(file, true)){
            // save was successful so discard the backup
            tempFile.delete();
        } else {
            // save failed so restore the backup
            tempFile.renameTo(file);
        }
    }

OLEオブジェクトのデアクティベート
Deactivating the OLE Object

もし、いろいろなOLEドキュメントやActiveXコントロールはアプリケーションに埋め込まれるなら 一度に一つのOLEオブジェクトだけがアクティブにしておくことが望ましいかもしれません。 現在使われていないOLEオブジェクトはデアクティベートしておくことができます。 OLEオブジェクトがデアクティベートされたとき、"Running"状態に置かれ、 内容は見えますが、ツールバーとメニューバーは除去され、マウスやキーボードの動きに反応しません。 この状態ではオブジェクトはまだ生きています。 アクティブな状態から戻るとき、オブジェクトに変更があったなら変更が現れます。

If several OLE Documents or ActiveX Controls are embedded in an application, it may be preferable to have only one OLE Object "active" at a time. The OLE Object that is not currently being used can be deactivated. When the OLE Object is deactivated, it is placed in a "Running" state – its contents are visible but the toolbar and menu bar have been removed and the content does not respond to mouse or keyboard actions. In this state, the object is still alive. If modifications have been made to the object, when the object is returned to the active state, those changes will still be present.

注意: OLEドキュメントの場合、アクティベートとデアクティベートの順番は大変重要です。 最初に古いドキュメントをデアクティベートしその後新しいドキュメントをアクティベートしなければメニューバーが正しく表示されません。

NOTE: In the case of OLE Documents, the order of activating and deactivating is very important – first deactivate the old document and then activate the new document otherwise the menu bar will not appear correctly.

OLEドキュメントとActiveXコントロールのデアクティベートは OleClientSiteOleControlSitedeactivateInPlaceClientを呼び出すことで行います。

Deactivating an OLE Document or ActiveX Control is done by calling deactivateInPlaceClient on the OleClientSite or OleControlSite:

    currentSite.deactivateInPlaceClient();

OLEオブジェクトの破棄
Disposing the OLE Object

OleFrameOleClientSiteそしてOleControlSiteはSWTウィジェットなので 親が破棄されると子が自動的に破棄されます。 他のOLEオブジェクトが同じOleFrameでまだ実行されているOLEドキュメントかActiveXコントロールを 終了するには直接オブジェクトを破棄します。

Because OleFrame, OleClientSite and OleControlSite are SWT Widgets, when the parent is disposed, the children will be disposed automatically. To terminate an OLE Document or ActiveX Control while other OLE Objects are still running in the same OleFrame, directly dispose of the object:

    myClientSite.dispose();

または

or

    myControlSite.dispose();

注意: OLEオブジェクトが終了したとき、保存は自動的には行われず、 "dirty"状態のチェックも行われません(閉じる前の未保存の確認が無い)。 アプリケーションはこのコードを書かなければいけません。

Note: When an OLE Object is terminated, saving is not performed automatically, nor will there be any checking for a "dirty" state (no checking for unsaved changes before closing). The application must write this code.

カスタマイズされた振る舞いを使う
Using Customized Behavior

ActiveXコントロールとOLEドキュメントはカスタマイズされた振る舞いを提供することができます。 カスタマイズされた振る舞いの種類をみるにはOLEオブジェクトに関連するタイプライブラリを参照することができます。 SWTは "Exec Command"、"IDispatch interface"、イベント、プロパティー変更通知といった いろいろな異なるタイプのカスタマイズされた振る舞いへのアクセスを提供します。

ActiveX Controls and OLE Documents can provide customized behavior. To see what kinds of customized behavior are available refer to the type library associated with the OLE Object. SWT provides access to several different types of customized behavior – the "Exec Command", the "IDispatch interface", Events and Property Change Notification.

Exec Command
Exec Command

"exec"コマンドは OLEドキュメントとActiveXコントロールの両方で定義済みのコマンドを送信する一般的な方法です。 コマンドの文法は次の通りです。

The "exec" command is a generic way of sending a predefined set of commands to either an OLE Document or an ActiveX Control. The command syntax is as follows:

    int OleClientSite.exec(int cmdID, int options, Variant in, Variant out)

where

inとoutのパラメータは どんなデータ型でもパスする総称的なOLEのメカニズムである、 Variantで定義されています。 Variantは整数、論理値、文字列や他の異なる種類のオブジェクトを含むことができます。

In and out parameters are defined using a Variant, which is the OLE mechanism for generically passing around any type of data. A Variant may contain an integer, a boolean, a string or many other different types of objects.

OLEオブジェクトはコマンドを認識するかもしれないし、しないかもしれません。 コマンドを送信する前にOLEオブジェクトにOleClientSite.queryStatus(int cmdID)を使ってコマンドを認識するか 尋ねることができます。 これは以下の値の組み合わせが返されます。

The OLE Object may or may not recognize the command. Before sending a command, you can ask an OLE Object if it recognizes the command using OleClientSite.queryStatus(int cmdID). This will return some combination of the following values:

ここにExecコマンドが利用の仕方の例があります。

Here is an example of how the Exec command is used:

    int result = controlSite.queryStatus(OLE.OLECMDID_PRINT);
    if ((result & OLE.OLECMDF_ENABLED) == OLE.OLECMDF_ENABLED) {
        controlSite.exec(OLE.OLECMDID_PRINT, OLE.OLECMDEXECOPT_PROMPTUSER, null, null);
    }

詳細 "exec": MSDN Library: Platform SDK->Component Services ->COM ->OLE and Data Transfer->Reference ->Interfaces->IOleCommandTarget

Further Reading on "exec": MSDN Library: Platform SDK->Component Services ->COM ->OLE and Data Transfer->Reference ->Interfaces->IOleCommandTarget

IDispatch または OLE オートメーション
IDispatch or OLE Automation

OLEドキュメントやActiveXコントロールは "exec"コマンドで定義された一般的なセット よりもリッチなコマンドのセットを提供できます。 これらにアクセスするにはIDispatchインターフェースを利用します。 たとえばWordはWord Basicの cut/copy/paste, print, spell check, select text, change paragraph format, などのすべての種類のコマンドへのアクセスを与えられた インターフェースをすべて提供しています。 SWTではIDispatchの機能はOleAutomationオブジェクトを使ってアクセスされます。

An OLE Document or ActiveX Control can also provide a much richer set of commands than the generic set defined for the "exec" command. To access these, use the IDispatch interface. IDispatch provides access to get and set property values and invoke methods. For example, Word provides the entire Word Basic interface that gives you access to all sorts of commands and properties like cut/copy/paste, print, spell check, select text, change paragraph format, etc. In SWT the IDispatch capabilities are accessed using the OleAutomation object.

Creating the Automation object:

OleAutomationオブジェクトはクライアントまたはコントロールサイトから生成することができ、 メソッドの呼び出しからの戻り値として得ることができます。

An OleAutomation object can be created from a client or control site or it can be obtained as the return value from a method invocation.

単純な例はWebブラウザです。 このようにアクセスできるnavigate,back, forward, home のようなコマンドを提供します。

A simple case is the Web Browser. It provides commands like navigate, back, forward, home which you can access like this:

    OleControlSite controlSite = new OleControlSite(frame, SWT.NONE, "Shell.Explorer");
    OleAutomation automation = new OleAutomation(controlSite);

プロパティの取得
Get a Property

プロパティーはOleAutomationのメソッドgetPropertyを 利用してOLEオブジェクトから得られます。

A Property is obtained from an OLE Object using the OleAutomation method getProperty:

    Variant getProperty(int dispIdMember)

where

例:

For example:

    OleControlSite controlSite = new OleControlSite(frame, SWT.NONE, "Shell.Explorer");
    OleAutomation automation = new OleAutomation(controlSite);
    int[] rgdispid = automation.getIDsOfNames(new String[]{"LocationName"});
    int dispIdMember = rgdispid[0];
    Variant result = automation.getProperty(dispIdMember);
    System.out.println("The Web Browser is currently viewing the URL "+result.getString());

タイプライブラリのレコードとの一致:

Matching type library record:

interface IWebBrowser : IDispatch {
    …
    [id(0x000000d2), propget, helpstring("Gets the short (UI-friendly) name of the URL/file currently viewed.")]
    HRESULT LocationName([out, retval] BSTR* LocationName);
    …
}

プロパティの設定
Set a Property

これは"Get a Property"ととても似ています。これの場合のメソッドは次のようになります。

This is very similar to "Get a Property". In this case the method is:

    boolean OleAutomation.setProperty(int dispIdMember, Variant rgvarg).

where

例:

For example:

    // Allow multiple selection in an embedded Calendar Control
    OleControlSite controlSite = new OleControlSite(frame, SWT.NONE, "MSComCtl2.MonthView");
    OleAutomation automation = new OleAutomation(controlSite);
    int[] rgdispid = automation.getIDsOfNames(new String[]{"MultiSelect"});
    int dispIdMember = rgdispid[0];
    Variant multiSelect = new Variant((short)1); // set to true (0 = false)
    automation.setProperty(dispIdMember, multiSelect);

タイプライブラリのレコードとの一致:

Matching type library record:

interface IMonthView : IDispatch {
    …
    [id(0x000000013), propput, helpstring("Allow multiple selection."), helpcontext(0x00030da8)]
    HRESULT MultiSelect([in] BSTR pbMultiSelect);
    …
}

コマンドの呼び出し
Invoke a Command

コマンドを呼び出すことは 複数のパラメータを通すこと、そしてこれらのパラメータのいくつかはオプショナルであることから 少し複雑で、パラメータの値と同じようにパラメータの識別子を通さなければいけません。 これに適応するためにOleAutomation.invokeには3つの変形があります。

Invoking a command is a bit more complicated because you can pass in multiple parameters and because some of these parameters may be optional, you must pass an identifier for the parameter as well as the value of the parameter. There are three variants on the OleAutomation.invoke method to accommodate this:

Where

例1:

Example 1:

Webブラウザの"GoForward"コマンドはパラメータをとりません

The "GoForward" command on the Web Browser takes no parameters:

    OleControlSite webSite = new OleControlSite(frame, SWT.NONE, "Shell.Explorer");
    OleAutomation automation = new OleAutomation(webSite);
    int[] rgdispid = automation.getIDsOfNames(new String[]{"GoForward"});
    int dispIdMember = rgdispid[0];
    Variant pVarResult = automation.invoke(dispIdMember);

注意: getIDsOfNamesを呼んでコマンドのIDを取得します

Note: Call getIDsOfNames to get the ID of the command

タイプライブラリのレコードとの一致:

Matching type library record:

interface IWebBrowser : IDispatch {
    …
    [id(0x00000065), helpstring("Navigates to the next item in the history list.")]
    HRESULT GoForward();
    …
}

例2:

Example 2:

Webブラウザの"Navigate"コマンドはいろいろな引数をとりますが、 ただ1つ"URL"という必須のパラメータがあります。 この例ではオプショナルな引数は送りません。

The "Navigate" command of the Web Browser takes several arguments but there is only one mandatory parameter and that is the "URL". In this example we are not going to send any of the optional arguments:

    OleControlSite controlSite = new OleControlSite(frame, SWT.NONE, "Shell.Explorer");
    OleAutomation automation = new OleAutomation(controlSite);
    int[] rgdispid = automation.getIDsOfNames(new String[]{"Navigate"});
    int dispIdMember = rgdispid[0];
    Variant[] rgvarg = new Variant[1]; // this is the URL parameter
    rgvarg[0] = new Variant("www.ibm.com");
    Variant pVarResult = automation.invoke(dispIdMember, rgvarg);

タイプライブラリのレコードとの一致:

Matching type library record:

interface IWebBrowser : IDispatch {
    …
    [id(0x00000068), helpstring("Navigates to a URL or file.")]
    HRESULT Navigate(
        [in] BSTR URL,
        [in, optional] VARIANT* Flags,
        [in, optional] VARIANT* TargetFrameName,
        [in, optional] VARIANT* PostData,
        [in, optional] VARIANT* Headers);
    …
}

例3:

Example 3:

Word Basicの"FormatFont"コマンドはいろいろなオプショナルなパラメータをとり、 そのうちのいくつかに興味があります。

The "FormatFont" command in Word Basic takes several optional parameters and we are interested in just a few of them:

    // This is a helper method for getting access to Word's WordBasic IDispatch interface
    // because it is rather complicated
    private OleAutomation getWordBasic(OleClientSite clientSite) {
        // Get generic IDispatch interface
        OleAutomation dispInterface = new OleAutomation(clientSite);
    
        // Get Application
        int[] appId = dispInterface.getIDsOfNames(new String[]{"Application"}); 
        if (appId == null) OLE.error(OLE.ERROR_APPLICATION_NOT_FOUND);
        Variant pVarResult = dispInterface.getProperty(appId[0]);
        if (pVarResult == null) OLE.error(OLE.ERROR_APPLICATION_NOT_FOUND);
        OleAutomation application = pVarResult.getAutomation();

        // Get Word Basic
        int[] wbId = application.getIDsOfNames(new String[]{"WordBasic"});
        if (wbId == null) OLE.error(OLE.ERROR_APPLICATION_NOT_FOUND);
        Variant pVarResult2 = application.getProperty(wbId[0]);
        if (pVarResult2 == null) OLE.error(OLE.ERROR_APPLICATION_NOT_FOUND);
        return pVarResult2.getAutomation();
    }

    OleClientSite clientSite = new OleClientSite(frame, SWT.NONE, "Word.Document");
    OleAutomation automation = getWordBasic(clientSite);
    // set the font to 12 point, Italic, Bold - ignore Color and Font name
    int[] rgdispid = automation.getIDsOfNames(
        new String[]{"FormatFont", "Points", "Color", "Font", "Bold", "Italic"});
    int dispIdMember = rgdispid[0];
    Variant[] rgvarg = new Variant[3];
    int[] rgdispidNamedArgs = new int[3];
    rgvarg[0] = new Variant(12); // this is the Points parameter
    rgdispidNamedArgs[0] = rgdispid[1];
    rgvarg[1] = new Variant(1); // this is the Bold parameter
    rgdispidNamedArgs[1] = rgdispid[4];
    rgvarg[2] = new Variant(1); // this is the Italic
    rgdispidNamedArgs[2] = rgdispid[5];
    automation.invokeNoReply(dispIdMember, rgvarg, rgdispidNamedArgs);

注意: ここでinvokeの代わりにinvokeNoReplyを使いました。 Wordはかつて最初に書かれたOLEドキュメントでした。 他のOLEドキュメントとわずかに異なって書かれています。 Wordコマンドが値を返さないとき、呼び出しに"InvokeNoReply"を使うべきです。 他のほとんどのOLEオブジェクトでは値が返されていなくても"invoke"を使うことができます。

Note: Here we have used invokeNoReply instead of invoke. Word was the first OLE Document ever written and as such it is written slightly differently than other OLE Documents. If a Word command does not return a value, you should use the "InvokeNoReply" variations of invoke. For most other OLE Objects, you can always use "invoke" even if there is no value returned.

詳細: MSDN Library: Books->Inside OLE->Chapter 14->The Mechanics of OLE Automation->The IDispatch Interface

Further Reading: MSDN Library: Books->Inside OLE->Chapter 14->The Mechanics of OLE Automation->The IDispatch Interface

コントロールのイベントとプロパティー変更
Events and Property changes in Controls

addEventListener - コントロールのイベントを受け取ることを許可する

addEventListener – allows the user to listen for Events on the Control.

例:

Example:

    // Respond to ProgressChange events in the Web Browser
    // by updating the applications Progress bar
    OleControlSite controlSite
         = new OleControlSite(frame, SWT.NONE, "Shell.Explorer");
    OleAutomation automation = new OleAutomation(controlSite);
    int ProgressChange = 108; //0x6C - obtained from the type library
    ProgressBar progressBar = new ProgressBar(shell, SWT.BORDER);
    controlSite.addEventListener(ProgressChange, new OleListener() {
        public void handleEvent(OleEvent event) {
            if (event.detail != ProgressChange) return;
            Variant progress = event.arguments[0];
            Variant maxProgress = event.arguments[1];
            if (progress == null || maxProgress == null) return;
            
            progressBar.setMaximum(maxProgress.getInt());
            progressBar.setSelection(progress.getInt());
        }
    });

注意: アプリケーションはイベント(ProgressChange)の識別子 とevent.argument (例ではevent.arguments[0]が現在の進行の値で event.arguments[1]が進行の最大値です) で与えられるデータの種類を知らなければいけません。 これらはタイプライブラリで見つけることができます。

Note: The application must know the identifier for the event (ProgressChange) and what kind of data it is being given in the event.argument (In our example event.arguments[0] is the current progress value and event.arguments[1] is the maximum progress value)– You can find this out from the type library:

dispinterface DWebBrowserEvents {
    …

    [id(0x0000006c), helpstring("Fired when download progress is updated.")]
        void ProgressChange(
            [in] long Progress, 
            [in] long ProgressMax);
    …
}

addPropertyListener - プロパティーの変更が起こる前に変更を拒否するオプションと プロパティーの変更が起こった後に通知することを許可します。

addPropertyListener – allows the user to be notified before property changes occur – with the option to veto the change – and after property change has occurred.

例:

Example:

    OleControlSite controlSite = new OleControlSite(frame, SWT.NONE, "Shell.Explorer");
    OleAutomation automation = new OleAutomation(controlSite);
    int[] rgdispid = automation.getIDsOfNames(new String[]{"ReadyState"});
    int READYSTATE = rgdispid[0];
    
    // Listen for changes to the ready state and print out the current state
    controlSite.addPropertyListener(READYSTATE, new OleListener() {
        public void handleEvent(OleEvent event) {
            if (event.detail == OLE.PROPERTY_CHANGING) {
                // Print out the old state
                Variant state = automation.getProperty(READYSTATE);
                System.out.println("Web State changing from " + state.getInt());
                event.doit = true; // allow property change to happen

            }
            if (event.detail == OLE.PROPERTY_CHANGED) {
                Variant state = automation.getProperty(READYSTATE);
                System.out.println("Web State changed to " + state.getInt());
            }
        }
    });

タイプライブラリに定義されたプロパティであれば変更を受け取ることができます。

You can listen for a change to any property defined in the type library.

タイプライブラリはプロパティー値を解釈するための列挙も含んでいます。 例えば前の例の"ReadyState"値は下記の列挙に属する整数値です。

The type library also contains enumerations that can be used to interpret the property values. For example the "ReadyState" values in the previous example are integer values belonging to the following enumeration:

    typedef enum {
        READYSTATE_UNINITIALIZED = 0,
        READYSTATE_LOADING = 1,
        READYSTATE_LOADED = 2,
        READYSTATE_INTERACTIVE = 3,
        READYSTATE_COMPLETE = 4
    } tagREADYSTATE;

要約
Summary

Windowsプラットフォームにおいて、 OLEオブジェクトをアプリケーションに追加することは ユーザーエクスペリエンスを広げます。 SWTはこれを SWTコンテナウィジェットにOLEオブジェクトを埋め込むことを許可することによって 簡単にし、オブジェクトのインターフェースをアプリケーションとユーザーが利用できるようにします。

On the Windows platform, adding OLE Objects to your application expands the user experience. SWT makes this easy to do by allowing OLE Objects to be embedded in SWT Container widgets, making the Object's interface available to your application, and therefore to your users.

Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.