External API の例:ActionScript と ActiveX を使用するデスクトップアプリケーションとの通信

Flash Player 9 以降

この例は、External API を使用した、ActiveX コントロールを使用するデスクトップアプリケーションと ActionScript との間の通信を示しています。 この例では、ActionScript コードおよび同じ SWF ファイルを含めて Introvert IM を再び使用しているため、ActionScript の External API の使用については説明しません。 前述の例をよく理解しておくと、この例を理解しやすくなります。

この例のデスクトップアプリケーションは、Microsoft Visual Studio .NET を使用して C# で記述されています。 説明の中心は、ActiveX コントロールを使用した External API の操作方法です。 この例は、次のことを示しています。

  • Flash Player ActiveX コントロールをホスティングしているデスクトップアプリケーションからの ActionScript 関数の呼び出し

  • ActionScript からの関数呼び出しの受信、および ActiveX コンテナでのその処理

  • ActiveX コンテナへのメッセージ送信に Flash Player が使用するプロキシクラスを使用した、直列化 XML フォーマットの詳細の非表示

このサンプルのアプリケーションのファイルを入手するには、www.adobe.com/go/learn_programmingAS3samples_flash_jp を参照してください。 Introvert IM C# ファイルは Samples/IntrovertIM_CSharp フォルダーにあります。 このアプリケーションは次のファイルで構成されています。

ファイル

説明

AppForm.cs

C# Windows Forms インターフェイスで構成されるメインアプリケーションファイル。

bin/Debug/IntrovertIMApp.swf

アプリケーションでロードされる SWF ファイル。

ExternalInterfaceProxy/ExternalInterfaceProxy.cs

External Interface との通信のための ActiveX コントロールのラッパーとして機能するクラス。 ActionScript を呼び出し、ActionScript からの呼び出しを受信するためのメカニズムを提供します。

ExternalInterfaceProxy/ExternalInterfaceSerializer.cs

Flash Player の XML フォーマットメッセージを .NET オブジェクトに変換するタスクを実行するクラス。

ExternalInterfaceProxy/ExternalInterfaceEventArgs.cs

このファイルは、カスタム Delegate とイベント引数という 2 つの C# タイプ(クラス)を定義します。これは、ActionScript からの関数呼び出しをリスナーに通知するため、ExternalInterfaceProxy クラスで使用されます。

ExternalInterfaceProxy/ExternalInterfaceCall.cs

このクラスは、関数名とパラメーターのプロパティを使用して、ActionScript から ActiveX コンテナへの関数呼び出しを表す値オブジェクトです。

bin/Debug/IntrovertIMApp.swf

アプリケーションでロードされる SWF ファイル。

obj/AxInterop.ShockwaveFlashObjects.dll、

obj/Interop.ShockwaveFlashObjects.dll

管理コードから Flash Player(Adobe Shockwave® Flash)ActiveX コントロールにアクセスする際に必要な Visual Studio .NET によって作成されたラッパーアセンブリ。

Introvert IM C# アプリケーションの概要

このサンプルアプリケーションは、互いに通信する 2 つのインスタントメッセージクライアントプログラム(1 つは SWF ファイル内、もう 1 つは Windows Forms に埋め込み)を示しています。 ユーザーインターフェイスには Shockwave Flash ActiveX コントロールのインスタンスが含まれ、ActionScript IM クライアントが格納された SWF ファイルがこのインスタンスにロードされます。 このインターフェイスには、Windows Forms IM クライアントを構成するいくつかのテキストフィールドも含まれています。1 つはメッセージ入力用フィールド(MessageText)で、もう 1 つはクライアント間で送信されるメッセージの複製(Transcript)を表示し、第 3 のフィールド(Status)は SWF IM クライアントで設定された availability ステータスを表示します。

Shockwave Flash ActiveX コントロールの追加

Shockwave Flash ActiveX コントロールを独自の Windows Forms アプリケーションに含めるには、最初にそれを Microsoft Visual Studio Toolbox に追加する必要があります。

コントロールをツールボックスに追加するには :

  1. Visual Studio Toolbox を開きます。

  2. Visual Studio 2003 の「Windows フォーム」セクション、または Visual Studio 2005 の任意のセクションを右クリックします。Visual Studio 2003 ではコンテキストメニューで項目の追加/削除を選択します。Visual Studio 2005 では「項目の選択」を選択します。

    これにより、ツールボックスのカスタマイズ(2003)ダイアログボックスまたはツールボックス項目の選択(2005)ダイアログボックスが表示されます。

  3. 「COM コンポーネント」タブを選択します。このタブには、Flash Player ActiveX コントロールなど、そのコンピューターにあるすべての COM コンポーネントが表示されます。

  4. スクロールして Shockwave Flash Object を探し、選択します。

    この項目が表示されない場合は、システムに Flash Player ActiveX がインストールされているか確認してください。

ActionScript から ActiveX コンテナへの通信について

External API を使用した ActiveX コンテナアプリケーションとの通信は、Web ブラウザーとの通信と同様になりますが、大きな違いが 1 つあります。 前述したように、ActionScript が Web ブラウザーと通信する場合、開発者が考慮している限り、関数は直接呼び出されます。関数の呼び出し方法と応答方法の詳細は、プレイヤー間で受け渡しできるようフォーマットされ、ブラウザーは認識されません。 ただし、ActiveX コンテナアプリケーションとの通信に External API が使用される場合、Flash Player はメッセージ(関数呼び出しおよび戻り値)をある XML フォーマットでアプリケーションに送信し、コンテナアプリケーションからの関数呼び出しと戻り値に同じ XML フォーマットが使用される必要があります。 ActiveX コンテナアプリケーションの開発者は、適切なフォーマットの関数呼び出しと応答を認識し、作成可能なコードを作成する必要があります。

サンプルの Introvert IM C# には、メッセージのフォーマッティング防止の可能なクラスが含まれていますが、ActionScript 関数の呼び出しおよび ActionScript からの呼び出しの受信時は、標準のデータ型を使用して操作することができます。 ExternalInterfaceProxy クラスを他のヘルパークラスと組み合わせるとこの機能が提供され、任意の .NET プロジェクトで再利用することで External API との通信が容易になります。

次のコードは、メインアプリケーションフォーム(AppForm.cs)から引用したもので、ExternalInterfaceProxy クラスを使用して実現された単純な操作を示しています。

public class AppForm : System.Windows.Forms.Form 
{ 
    ... 
    private ExternalInterfaceProxy proxy; 
    ... 
    public AppForm() 
    { 
        ... 
        // Register this app to receive notification when the proxy receives 
        // a call from ActionScript. 
        proxy = new ExternalInterfaceProxy(IntrovertIMApp); 
        proxy.ExternalInterfaceCall += new ExternalInterfaceCallEventHandler(proxy_ExternalInterfaceCall); 
        ... 
    } 
    ...

このアプリケーションは、proxy という名前の ExternalInterfaceProxy インスタンスを宣言して作成し、参照をユーザーインターフェイスの Shockwave Flash ActiveX コントロールに渡します(IntrovertIMApp)。次に、プロキシの ExternalInterfaceCall イベントを受信するための proxy_ExternalInterfaceCall() メソッドが、コードで登録されます。このイベントは、Flash Player から関数呼び出しがあったときに ExternalInterfaceProxy クラスによって送出されます。 このイベントへのサブスクライブは、C# コードが ActionScript からの関数呼び出しを受信し、応答する方法になっています。

ActionScript から関数呼び出しがあると、ExternalInterfaceProxy インスタンス(proxy)はその呼び出しを受信し、それを XML フォーマットに変換します。そして、プロキシの ExternalInterfaceCall イベントのリスナーとなっているオブジェクトに通知します。AppForm クラスの場合、proxy_ExternalInterfaceCall() メソッドでは次のようにイベントが処理されます。

    /// <summary> 
    /// Called by the proxy when an ActionScript ExternalInterface call 
    /// is made by the SWF 
    /// </summary> 
    private object proxy_ExternalInterfaceCall(object sender, ExternalInterfaceCallEventArgs e) 
    { 
        switch (e.FunctionCall.FunctionName) 
        { 
            case "isReady": 
                return isReady(); 
            case "setSWFIsReady": 
                setSWFIsReady(); 
                return null; 
            case "newMessage": 
                newMessage((string)e.FunctionCall.Arguments[0]); 
                return null; 
            case "statusChange": 
                statusChange(); 
                return null; 
            default: 
                return null; 
        } 
    } 
    ...

このメソッドは、ExternalInterfaceCallEventArgs インスタンスに渡されます。この例のインスタンス名は e です。これにより、このオブジェクトが ExternalInterfaceCall クラスのインスタンスである FunctionCall プロパティを取得します。

ExternalInterfaceCall インスタンスが、2 つのプロパティを持つ単純な値オブジェクトです。 FunctionName プロパティには、ActionScript ExternalInterface.Call() ステートメントで指定された関数名が格納されています。ActionScript に何らかのパラメーターが追加されると、そのパラメーターは ExternalInterfaceCall オブジェクトの Arguments プロパティに格納されます。この場合、イベントを処理するメソッドは、トラフィックマネージャーのように機能する switch ステートメントです。FunctionName プロパティの値(e.FunctionCall.FunctionName)によって、AppForm クラスのどのメソッドが呼び出されるかが決まります。

前述のコードの switch ステートメントのブランチは、一般的なメソッド呼び出しシナリオを示しています。例えば、すべてのメソッドは値を ActionScript に返すか(isReady() メソッド呼び出しなど)、null を返す(他のメソッド呼び出しの場合)必要があります。ActionScript から渡されたパラメーターへのアクセスは、newMessage() メソッド呼び出しに示されています(このメソッド呼び出しにより、Arguments 配列の第 1 エレメントであるパラメーター e.FunctionCall.Arguments[0] が渡されます)。

ExternalInterfaceProxy クラスを使用した C# からの ActionScript 関数の呼び出しは、ActionScript からの関数呼び出しの受信よりもはるかに単純です。 ActionScript 関数を呼び出すには、次のように ExternalInterfaceProxy インスタンスの Call() メソッドを使用します。

    /// <summary> 
    /// Called when the "Send" button is pressed; the value in the 
    /// MessageText text field is passed in as a parameter. 
    /// </summary> 
    /// <param name="message">The message to send.</param> 
    private void sendMessage(string message) 
    { 
        if (swfReady) 
        { 
            ... 
            // Call the newMessage function in ActionScript. 
            proxy.Call("newMessage", message); 
        } 
    } 
    ... 
    /// <summary> 
    /// Call the ActionScript function to get the current "availability" 
    /// status and write it into the text field. 
    /// </summary> 
    private void updateStatus() 
    { 
        Status.Text = (string)proxy.Call("getStatus"); 
    } 
    ... 
}

この例で示されているように、ExternalInterfaceProxy クラスの Call() メソッドは、ActionScript の ExternalInterface.Call() メソッドと非常によく似ています。第 1 パラメーターはストリングで、呼び出す関数の名前になります。 その他のパラメーター(ここには示されていません)も ActionScript 関数に渡されます。 ActionScript 関数から値が返された場合、その値は Call() メソッドで返されます(前述の例)。

ExternalInterfaceProxy クラスの内部

ActiveX コントロールのプロキシラッパーを使用することは必ずしも重要ではなく、独自のプロキシクラス(例えば、別のプログラミング言語や別のプラットフォーム用)を作成することもできます。 プロキシの作成についてはここで詳しく説明しませんが、この例におけるプロキシクラスの内部処理を理解することは有益です。

Shockwave Flash ActiveX コントロールの CallFunction() メソッドを使用すると、External API を使用して ActiveX コンテナから ActionScript 関数を呼び出すことができます。次の ExternalInterfaceProxy クラスの Call() メソッドの一部は、これを示しています。

// Call an ActionScript function on the SWF in "_flashControl", 
// which is a Shockwave Flash ActiveX control. 
string response = _flashControl.CallFunction(request);

このコード部分で、_flashControl は Shockwave Flash ActiveX コントロールです。ActionScript 関数呼び出しは、CallFunction() メソッドを使用して行われます。このメソッドにはパラメーターが 1 つあり(この例では request)、このパラメーターは XML フォーマットされた命令の含まれたストリングです。呼び出される ActionScript 関数の名前および任意のパラメーターが含まれています。ActionScript から返されたすべての値は XML フォーマットストリングにエンコードされ、CallFunction() 呼び出しの戻り値として送り返されます。この例では、この XML ストリングが response 変数に格納されます。

ActionScript からの関数呼び出しの受信は、段階的な手順で行われます。 ActionScript から関数呼び出しがあると、Shockwave Flash ActiveX コントロールは FlashCall イベントを送出するため、SWF ファイルからの呼び出しを受信するためのクラス(ExternalInterfaceProxy クラスなど)ではそのイベント用のハンドラーを定義しておく必要があります。 ExternalInterfaceProxy クラスでは、このイベントハンドラー関数の名前は _flashControl_FlashCall() で、クラスコンストラクター内のイベントを待ち受けるよう登録されています。

private AxShockwaveFlash _flashControl; 
 
public ExternalInterfaceProxy(AxShockwaveFlash flashControl) 
{ 
    _flashControl = flashControl; 
    _flashControl.FlashCall += new _IShockwaveFlashEvents_FlashCallEventHandler(_flashControl_FlashCall); 
} 
... 
private void _flashControl_FlashCall(object sender, _IShockwaveFlashEvents_FlashCallEvent e) 
{ 
    // Use the event object's request property ("e.request") 
    // to execute some action. 
    ... 
    // Return a value to ActionScript; 
    // the returned value must first be encoded as an XML-formatted string. 
    _flashControl.SetReturnValue(encodedResponse); 
}

イベントオブジェクト(e)には request プロパティ(e.request)があります。このプロパティは、関数名やパラメーターなど、関数呼び出しに関する情報が XML フォーマットで格納された文字列になっています。この情報をコンテナで使用すると、実行するコードを判別できます。 ExternalInterfaceProxy クラスでは、要求が XML フォーマットから ExternalInterfaceCall オブジェクトに変換され、同じ情報がアクセスしやすい形式で提供されます。 ActiveX コントロールの SetReturnValue() メソッドを使用すると、関数の結果を ActionScript の呼び出し側に返すことができます。この場合も、得られたパラメーターを External API で使用される XML フォーマットにエンコードする必要があります。

Shockwave Flash ActiveX コントロールをホストするアプリケーションと ActionScript 間の通信では、関数呼び出しと値をエンコードする際に専用の XML フォーマットが使用されます。 サンプルの Introvert IM C# では、ExternalInterfaceProxy クラスによって、アプリケーションフォーム内のコードで、Flash Player で使用する XML フォーマットの詳細を無視して、ActionScript との間で受け渡す値を直接操作できるようになっています。 これを実現するため、ExternalInterfaceProxy クラスでは ExternalInterfaceSerializer クラスのメソッドを使用して、実際に XML メッセージを .NET オブジェクトに変換しています。 ExternalInterfaceSerializer クラスには、次の 4 つのパブリックメソッドがあります。

  • EncodeInvoke():引数の関数名と C# ArrayList を適切な XML フォーマットにエンコードします。

  • EncodeResult():結果値を適切な XML フォーマットにエンコードします。

  • DecodeInvoke():ActionScript からの関数呼び出しをデコードします。FlashCall イベントオブジェクトの request プロパティは DecodeInvoke() メソッドに渡され、このメソッドで呼び出しが ExternalInterfaceCall オブジェクトに変換されます。

  • DecodeResult():ActionScript 関数の呼び出しの結果として受信した XML をデコードします。

これらのメソッドは、C# の値を External API の XML フォーマットにエンコードし、XML を C# オブジェクトにデコードします。Flash Player で使用する XML フォーマットについて詳しくは、External API の XML フォーマットを参照してください。