ActiveX コントロール

イントロダクション

Curl® 言語では、アプレットの中に、 ActiveX® コントロールとして利用できるリソースを挿入することが出来ます。 そのようなリソースの例として、Flash™ ムービー、 QuickTime™ ムービー や Microsoft® Internet Explorer などが挙げられます。 追加するプロセスは、OBJECT や EMBED HTML タグをいれるプロセスと似ています。
ActiveX API はサポートしている全てのOSで利用することができますが、Windows 以外のプラットフォーム上での実行時には ActiveX コントロールが利用できないため ActiveXException がスローされます。このスローされる例外は、Windows 上でActiveXコントロールがインストールされていない状況で、アプレットがその実存しないコントロールにアクセスしようとする時にスローされる例外と同じです。このような例外を処理するアプレットは、全てのプラットフォームでも最低限の機能を処理できるようにプログラムする必要があります。
Curl RTEは、ブロッキングされたHTTP呼び出しの間中、ActiveXイベントを処理します。ActiveX オブジェクト上のイベント ハンドラは、いかなる種類のイベント ループに入らないよう、またブロッキングされたHTTP呼び出しを行わないように注意する必要があります。

ActiveX コントロールを Curl アプレットに追加する

ActiveX コントロールのインスタンスを作成し、そのインスタンスのメソッドとフィールドを使用するためには、Curl® 言語の ActiveXObject クラスを使用します。ActiveXObject クラスはGraphic のサブクラスです。そのため、Curl アプレットに ActiveXObject を挿入することが出来ます。(子オブジェクトをトップに展開する Box に配置されると、ActiveXGraphic は常に他の子オブジェクトのトップに配置されます。これは ActiveXGraphic が新規のホスト ウィンドウを作成するためです。)
注意: このチャプターで使用されているコード例では、他のチャプターで見られるような例とは違い、 ページ上から直に実行することは出来ません。[ ActiveX オブジェクトは特権があるアプレット からのみ生成可能なためです。]

以下にある例を実行するためには、コード例を、空のアプレットのファイルにコピーしてから実行します。 そのアプレットは、特権付きロケーションに保存されている必要があります。 特権を与えるには、Curl コントロールパネルを使用してください。 特権に関しての詳しい内容は開発者ガイドの「 特権付アプレット」 を参照してください。
以下の例では、Microsoft®のカレンダー コントロール を作成し、Frame に挿入します。 ActiveXObject のファクトリの引数として、Program ID または Class ID を挿入します。 ActiveX オブジェクトの program ID と Class ID は、そのオブジェクトのドキュメンテーションから引用・コピーすることが出来ます。 Program ID は、引用符の中に入れる必要があります。 Class ID は、逐語的文字列として使用します。 逐語的文字列の詳しい内容は、開発者ガイドの「逐語的文字列」 を参照してください。

コード例

特権付のロケーションに以下のアプレットをコピーしてください。
{import * from CURL.GRAPHICS.ACTIVEX}

|| ActiveX カレンダー コントロール
{let xobj:ActiveXObject =
    {ActiveXObject
||        program id を使用
||        ProgId = "mscal.calendar"
||        class id を使用
        ClsId = |"{8E27C92B-1264-101C-8A2F-040224009C02}"|
    }
}

{value
    {Frame
        border-color = "black",
        border-width = 2px,
        margin = 2px,
        background = "blue",
        {ActiveXGraphic
            width = 8cm,
            height = 8cm,
            xobj
        }
    }
}
{do
    {set xobj.Year = 1998}
}

ActiveX コントロールのメソッドを参照する

使用できるメソッドを参照するには、ActiveXMethodInfo オブジェクトをリターンする ActiveXObject.get-method-info を使用します。

同様に、ゲッターやセッターについて参照するには、 ActiveXFieldInfo オブジェクトをリターンする、ActiveXObject.get-getter-info または ActiveXObject.get-setter-infoを使用してください。
以下の例では、Microsoft カレンダー オブジェクトの、メソッド、ゲッター、 セッターを記述するメソッドが使用されています。

コード例

特権付のロケーションに以下のアプレットをコピーしてください。
{applet
    {compiler-directives
        stringent? =  true
    }
}
{import * from CURL.GRAPHICS.ACTIVEX}
{import ActiveXGraphic from CURL.GUI.BASE}

{let activex-object:ActiveXObject =
    {ActiveXObject
        ProgId = "mscal.calendar"
    }
}
{let method-info-graphic:VBox = {VBox}}
{let num-methods:int = activex-object.method-count}
{do
    {method-info-graphic.add {HBox {bold Methods}}}
    {method-info-graphic.add
        {HBox "Number of methods: ", num-methods}
    }
    {for i:int = 0 below num-methods do
        let method-info:ActiveXMethodInfo = {activex-object.get-method-info i}
        {method-info-graphic.add
            {HBox "Name: ", method-info.name}
        }
        {if-non-null description = method-info.description then
            {method-info-graphic.add
                {TextFlowBox "Description: ", {value method-info.description}}}
        }

        {method-info-graphic.add
            {HBox "Num args: ", method-info.arg-count}
        }
        {for i:int = 0 below method-info.arg-count do
            {let thistype:ActiveXArgInfo = {method-info.arg-type i}}
            {method-info-graphic.add
                {format "Arg %d: %s", i, thistype.type}
            }

        }
        {method-info-graphic.add {hrule}}
    }
    {method-info-graphic.add {HBox {bold Setters}}}

    let num-setters:int = activex-object.setter-count
    {method-info-graphic.add
        {HBox "Number of setters: ", num-setters}
    }

    {for i:int = 0 below num-setters do
        let setter-info:ActiveXFieldInfo = {activex-object.get-setter-info i}
        {method-info-graphic.add
            {HBox "Setter Name: ", setter-info.name}
        }
        {if-non-null description = setter-info.description then
            {method-info-graphic.add {HBox "Description: ", description}}
        }
        {method-info-graphic.add {HBox "Type: ", setter-info.type.type}}
        {method-info-graphic.add {hrule}}
    }
    {method-info-graphic.add {HBox {bold Getters}}}

    let num-getters:int = activex-object.getter-count
    {method-info-graphic.add
        {HBox "Number of getters: ", num-getters}
    }

    {for i:int = 0 below num-getters do
        let getter-info:ActiveXFieldInfo =
            {activex-object.get-getter-info i}
        {method-info-graphic.add
            {HBox "Getter Name: ", getter-info.name}
        }
        {if-non-null description = getter-info.description then
            {method-info-graphic.add
                {HBox "Description: ", description}
            }
        }
        {method-info-graphic.add {HBox "Type: ", getter-info.type.type}}
        {method-info-graphic.add {hrule}}
    }
}
{value
    method-info-graphic
}


Curl のデータ型と ActiveX コントロール

Curlのアプレットで ActiveX コントロールを使用する際には、COM メソッドに渡す Curl のオブジェクトがどういう種類のものかということを知っておく必要があります。次の表は、COM 型と Curl のデータ型の間のマッピングを示しています。方向 列の矢印は、型の変換が一方向でのみ有効なケースを示しています。
Curl のデータ型から COM 型への変換は、式のスタティックな型ではなく、Curlの値の実行時の型に基づいています。Curl では null 値は1つだけで、これはすべての # 型に共通であり、スタティックな型でありながら VT_NULL に変換されます。
ActiveX の型方向Curl のデータ型
VT_EMPTYnull
VT_NULLnull
VT_BSTRStringInterface
VT_BSTR#String
VT_BOOLbool
VT_I1int8
VT_I2int16
VT_I4int32
VT_I8int64
VT_UI1uint8
VT_UI2uint16
VT_UI4uint32
VT_UI4char
VT_UI8uint64
VT_INTint32
VT_UINTuint32
VT_R4float
VT_R8double
VT_DISPATCH#ActiveXObject
VT_UNKNOWN#ActiveXObject
VT_DATEActiveXDate
VT_CYActiveXCurrency
VT_DECIMALActiveXDecimal
VT_ARRAY | ...#{FastArray-of ...}
VT_ARRAY | VT_VARIANT#{FastArray-of any}
VT_BYREF | ...#{Reference-to ...}
VT_BYREF | VT_VARIANT#{Reference-to any}
<引数が省略されている場合>SkipOptionalArg

ActiveX コントロールの削除

ActiveXObject.destroy-object ActiveXGraphic.destroy-object を使用して、ActiveXObjectのインスタンスを 削除することができます。削除されない場合は、ガーベッジコレクションで消去されるか、 または、アプレットのスレッドが消滅するまで、 ActiveXObject のインスタンスはメモリー の中に存在することになります。
ActiveXObject.destroy-object は、ActiveX オブジェクトとそのオブジェクトに関連した ActiveX コントロールを削除します。 このメソッドは ActiveXObject から一回だけコールすることが出来ます。 アクセッサの ActiveXObject.object-destroyed? を使用して、 オブジェクトが既に削除されたかチェックすることができます。
もし、ActiveXObjectActiveXGraphic にパスされている場合は、このメソッドを使用 することはできません。その場合は、ActiveXGraphic.destroy-object を使用してください。 ActiveXGraphic.object-destroyed? を使用して、オブジェクトが既に消去されたかを確認することが可能です。

COM/ActiveX 型ライブラリから Curl 言語コードの生成

Curl IDE には、Curl のネィティブ クラスで ActiveXObject をラップする Curl 言語コードを生成するスクリプトが含まれています。スクリプトは、generate-tlb-code.xcurl と呼ばれ、d:\automated-build-temp\build\win32-atom\ide\bin にあります。Curl スクリプトの記述と使用に関する詳細は、スクリプト を参照してください。
この機能は、 Curl Pro/IDE バージョンでだけ利用することが出来ます。 Curl と Curl Pro 製品 を参照してください。
以下のシンタックスを使用して、generate-tlb-code.xcurl スクリプトを実行します。:
Syntax:curl generate-tlb-code.xcurl [flags] type-library-file
flags の意味:
  • (--help | --usage | -h | -?)
    コマンドライン オプションと共にヘルプ メッセージを出力します。
  • (--out | -o) output-url
    指定された出力 url またはパスにコードを書き込みます。 指定されない場合は、コードは標準出力に出力されます。
  • (--filter | -f)
    カンマまたは、スペースで区切られた API のリスト。 リスト内の API のコードだけが生成されます。指定された API が 追加のインターフェース クラスを必要とする場合には、そのくらすの コードも生成します。
  • (--filter-file | -ff)
    カンマ、スペースまたは改行で区切られた API のリストを含むファイルの URL または、パス。--filter フラグにより、指定された API と その API が必要とする追加のインターフェース クラスのコードだけが 生成されます。
  • (--package-prefix | -p)
    生成されるコード内のパッケージ宣言で使用されるパッケージ プレフィクス。
  • (--versions | -v)
    生成されたコード内のパッケージ内にリストされる Curl API バージョン。 -p または --package-prefix がパッケージ宣言を取得する為に指定されなければ なりません。
生成されたコードは、6.0 以上の Curl RTE で動作します。生成されたコードは、各インターフェースのクラスと 'coclass' および型ライブラリ内で説明される各列挙型の定数を含みます。他の情報の型は、生成されたコードでサポートされません。インターフェースの為に生成されたクラスや、'coclass' は、パラメータとして既に生成されている ActiveXObject を取る既定のコンストラクタを持ちます。'coclass' の為に生成されたクラスは、また 'coclass' から新しい COM オブジェクトを作成する create-object コンストラクタも持ちます。'coclass' の為に生成されたクラスは、ActiveXObject の為に、obj という名前のフィールドをもち、インターフェースの為に生成されたクラスは、ActiveXObject の為に、<class name>-obj という名前のゲッターを持ちます。ActiveXObject の使用を終える時には、直接的または間接的に ActiveXObject.destroy-object を呼び出さなければなりません。'coclass' の為に生成されたクラス上で destroy-object を呼び出すことによってそれを呼び出すことも出来ます。
生成されたコード内のメソッドは、型ライブラリからの名前を持ちますが、'source' または、set-callback-<method name> を呼び出すイベント インターフェースのメソッドは例外で、コールバック プロシージャを取ります。生成されたコード上のプロパティは、通常、型ライブラリからの名前でゲッター、セッターが実装されます。しかし、プロパティが、追加のパラメータを取る場合は、get-<property name> または、set-<property name> という名前のメソッドが代わりに精製されます。'putref' プロパティはサポートされません。
'enum' の為に生成されたコードは、通常グローバル定数のセットで、型ライブラリからの名前になります。しかし、衝突する名前がある場合には、'enum' 値は、<enum type name>-<enum value name> になります。'enum' が非整数型の値を含む場合には、Curl 言語列挙型が代わりに使用されます。