Exemple d’API externe : communications entre ActionScript et une application de bureau qui utilise le contrôle ActiveX

Flash Player 9 et ultérieur

Cet exemple illustre l’utilisation de l’API externe pour communiquer entre ActionScript et une application de bureau utilisant le contrôle ActiveX. Il réutilise l’application Introvert IM, y compris le code ActionScript et le fichier SWF. Pour cette raison, aucune description de l’utilisation de l’API externe dans ActionScript n’est fournie. Il est recommandé de se familiariser avec l’exemple précédent pour mieux comprendre celui-ci.

L’application de bureau de cet exemple est écrite en C# à l’aide de Microsoft Visual Studio .NET. L’étude se concentre sur les techniques propres à l’utilisation de l’API externe conjointement avec le contrôle ActiveX. Cet exemple présente les points suivants :

  • Appel des fonctions ActionScript à partir d’une application de bureau hébergeant le contrôle ActiveX Flash Player

  • Réception des appels de fonction à partir d’ActionScript et traitement de ces appels dans un conteneur ActiveX

  • Utilisation d’une classe proxy pour masquer les détails du format XML sérialisé que Flash Player utilise pour les messages envoyés au conteneur ActiveX

Pour obtenir les fichiers d’application de cet exemple, voir www.adobe.com/go/learn_programmingAS3samples_flash_fr. Les fichiers de l’application Introvert IM C# se trouvent dans le dossier Samples/IntrovertIM_CSharp. L’application se compose des fichiers suivants :

Fichier

Description

AppForm.cs

Fichier d’application principal contenant l’interface de Windows Forms C#.

bin/Debug/IntrovertIMApp.swf

Fichier SWF chargé par cette application.

ExternalInterfaceProxy/ExternalInterfaceProxy.cs

Classe servant d’enveloppe au contrôle ActiveX pour la communication avec l’interface externe. Elle fournit les mécanismes d’appel et de réception des appels issus d’ActionScript.

ExternalInterfaceProxy/ExternalInterfaceSerializer.cs

Classe chargée de la conversion des messages au format XML de Flash Player en objets .NET.

ExternalInterfaceProxy/ExternalInterfaceEventArgs.cs

Fichier définissant deux types (classes) C# : une classe delegate personnalisée et une classe event arguments, utilisées par la classe ExternalInterfaceProxy pour notifier à un écouteur un appel de fonction provenant d’ActionScript.

ExternalInterfaceProxy/ExternalInterfaceCall.cs

Cette classe est un objet valeur représentant un appel de fonction d’ActionScript vers le conteneur ActiveX, avec des propriétés destinées au nom de fonction et aux paramètres.

bin/Debug/IntrovertIMApp.swf

Fichier SWF chargé par cette application.

obj/AxInterop.ShockwaveFlashObjects.dll,

obj/Interop.ShockwaveFlashObjects.dll

Ensembles d’enveloppes créés par Visual Studio .NET et requis pour accéder au contrôle ActiveX Flash Player (Adobe Shockwave® Flash) à partir du code géré.

Présentation de l’application Introvert IM C#

Cette application exemple est constituée de deux programmes client de messagerie instantanée qui communiquent entre eux ; l’un réside dans un fichier SWF et l’autre est élaboré dans Windows Forms. L’interface utilisateur comprend une occurrence du contrôle ActiveX Shockwave Flash, dans laquelle le fichier SWF contenant le client de messagerie ActionScript est chargé. L’interface comprend également plusieurs champs de texte qui constituent le client de messagerie Windows Forms IM : un champ permet d’entrer des messages (MessageText), un autre affiche la transcription des messages échangés par les clients (Transcript) et un troisième (Status) affiche le statut de disponibilité défini dans le client de messagerie SWF.

Intégration du contrôle ActiveX Shockwave Flash

Pour intégrer le contrôle ActiveX Shockwave Flash dans votre application Windows Forms, vous devez d’abord l’ajouter aux outils de Microsoft Visual Studio.

Pour ajouter le contrôle à la boîte à outils :

  1. Ouvrez la boîte à outils Visual Studio.

  2. Cliquez du bouton droit sur la section Windows Forms de Visual Studio 2003 ou toute section de Visual Studio 2005. Dans le menu contextuel, sélectionnez Ajouter/Supprimer des éléments dans Visual Studio 2003 (Choisir des éléments dans Visual Studio 2005).

    La boîte de dialogue Personnaliser la boîte à outils (2003) / Choisir les éléments de la boîte à outils (2005) s’ouvre.

  3. Sélectionnez l’onglet Composants COM, qui répertorie tous les composants COM disponibles sur votre ordinateur, y compris le contrôle ActiveX Flash Player.

  4. Localisez l’option Objet Shockwave Flash et sélectionnez-la.

    Si cette option n’apparaît pas, vérifiez que le contrôle ActiveX Flash Player est installé sur votre système.

Présentation de la communication d’ActionScript vers le conteneur ActiveX

La communication entre l’API externe et une application conteneur ActiveX est semblable à celle établie avec un navigateur Web, avec cependant une importante différence. Comme décrit plus haut, lorsque ActionScript communique avec un navigateur Web, du point de vue du développeur les fonctions sont appelées directement. Les détails du formatage des appels de fonction et des réponses en vue de leur transmission entre le lecteur et le navigateur sont masqués. Toutefois, lorsque l’API externe sert à communiquer avec une application conteneur ActiveX, Flash Player envoie des messages (appels de fonction et valeurs de retour) à l’application dans un format XML spécifique. Elle attend ensuite des appels de fonction et des valeurs de retour d’un format identique de la part de l’application conteneur. Le développeur de l’application conteneur ActiveX doit impérativement écrire un code capable de comprendre et de créer des appels de fonction et des réponses dans le format approprié.

L’exemple Introvert IM C# inclut un jeu de classes qui permet d’éviter le formatage des messages. Vous pouvez alors utiliser les types de données standard pour l’appel de fonctions ActionScript et la réception d’appels de fonction à partir d’ActionScript. Cette fonctionnalité est fournie par la classe ExternalInterfaceProxy, ainsi que d’autres classes d’aide. Ces classes peuvent s’utiliser dans tout projet .NET afin de faciliter la communication avec l’API externe.

Les sections de code suivant, extraites du formulaire principal de l’application (AppForm.cs), illustrent de manière simplifiée l’interaction obtenue grâce à la classe 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); 
        ... 
    } 
    ...

L’application déclare et crée une occurrence de ExternalInterfaceProxy appelée proxy en transmettant une référence au contrôle ActiveX Shockwave Flash qui se trouve dans l’interface utilisateur (IntrovertIMApp). Ensuite, le code enregistre la méthode proxy_ExternalInterfaceCall() afin qu’elle reçoive l’événement ExternalInterfaceCall du proxy. Cet événement est distribué par la classe ExternalInterfaceProxy lorsqu’un appel de fonction provient de Flash Player. La souscription à cet événement permet au code C# de recevoir et répondre aux appels de fonction issus d’ActionScript.

Lorsqu’un appel de fonction provient d’ActionScript, l’occurrence de ExternalInterfaceProxy (proxy) reçoit l’appel, le convertit au format XML et notifie les objets désignés comme écouteurs de l’événement ExternalInterfaceCall du proxy. Dans le cas de la classe AppForm, la méthode proxy_ExternalInterfaceCall() gère cet événement, comme suit :

    /// <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; 
        } 
    } 
    ...

Une occurrence de ExternalInterfaceCallEventArgs (appelée e dans cet exemple) est transmise à la méthode. Cet objet possède alors une propriété FunctionCall qui est une occurrence de la classe ExternalInterfaceCall.

Une occurrence de ExternalInterfaceCall est un simple objet valeur avec deux propriétés. La propriété FunctionName contient le nom de fonction spécifié dans l’instruction ExternalInterface.Call() ActionScript. Si des paramètres sont ajoutés dans ActionScript, ils sont inclus dans la propriété Arguments de l’objet ExternalInterfaceCall. Dans ce cas, la méthode qui gère l’événement est une simple instruction switch qui agit comme gestionnaire de trafic. La valeur de la propriété FunctionName (e.FunctionCall.FunctionName) détermine quelle méthode de la classe AppForm est appelée.

Dans l’exemple de code précédent, les branches de l’instruction switch illustrent des scénarios courants d’appel de fonction. Par exemple, toute méthode doit renvoyer une valeur à ActionScript (notamment l’appel de méthode isReady()) ou renvoyer la valeur null (comme illustré dans les autres appels de méthode). L’accès aux paramètres transmis à partir d’ActionScript est illustré par l’appel de la méthode newMessage() (qui transmet un paramètre e.FunctionCall.Arguments[0], le premier élément du tableau Arguments).

L’appel d’une fonction ActionScript à partir de C# à l’aide de la classe ExternalInterfaceProxy se fait de manière encore plus directe que la réception d’un appel de fonction à partir d’ActionScript. Pour appeler une fonction ActionScript, vous utilisez la méthode Call() de la classe ExternalInterfaceProxy, comme suit :

    /// <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"); 
    } 
    ... 
}

Comme le montre cet exemple, la méthode Call() de la classe ExternalInterfaceProxy est très semblable à son équivalent dans ActionScript, ExternalInterface.Call(). Le premier paramètre est une chaîne, le nom de la fonction à appeler. Tout autre paramètre supplémentaire (non illustré ici) est transmis dans la fonction ActionScript. Si cette fonction renvoie une valeur, cette dernière est renvoyée par la méthode Call() (comme le montre l’exemple ci-dessus).

Fonctionnement interne de la classe ExternalInterfaceProxy

L’utilisation de l’enveloppe proxy autour du contrôle ActiveX n’est pas toujours pratique ou vous préférerez parfois écrire votre propre classe proxy (par exemple dans un langage de programmation différent ou à destination d’une autre plate-forme). Bien que cette section n’aborde pas tous les détails de la création d’une telle classe, il est intéressant de comprendre le fonctionnement interne de la classe proxy présentée dans cet exemple.

La méthode CallFunction() du contrôle ActiveX Shockwave Flash vous permet d’appeler une fonction ActionScript à partir du conteneur ActiveX via l’API externe. Cette procédure est illustrée dans cet extrait tiré de la méthode Call() de la classe ExternalInterfaceProxy :

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

Dans cet extrait de code, _flashControl est le contrôle ActiveX Shockwave Flash. Les appels de fonction ActionScript s’effectuent au moyen de la méthode CallFunction(). Cette méthode prend un seul paramètre (request dans cet exemple) qui correspond à une chaîne contenant les instructions au format XML, c’est-à-dire le nom de la fonction ActionScript à appeler et les paramètres éventuels. Toute valeur renvoyée par ActionScript est convertie en une chaîne au format XML puis renvoyée comme valeur de retour de l’appel CallFunction(). Dans cet exemple, la chaîne XML est stockée dans la variable response.

La réception d’un appel de fonction issu d’ActionScript est un processus en plusieurs étapes. Les appels de fonction issus d’ActionScript provoquent la distribution de l’événement FlashCall du contrôle ActiveX Shockwave Flash. Ainsi, une classe (telle que ExternalInterfaceProxy) destinée à recevoir des appels d’un fichier SWF doit définir un gestionnaire pour cet événement. Dans la classe ExternalInterfaceProxy, la fonction gestionnaire d’événement est appelée _flashControl_FlashCall() et enregistrée dans le constructeur de classe pour écouter l’événement, comme suit :

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); 
}

L’objet événement (e) a une propriété request (e.request) qui correspond à une chaîne contenant des informations sur l’appel de fonction, telles que le nom de fonction et les paramètres, au format XML. Ces informations sont utilisées par le conteneur pour déterminer le code à exécuter. Dans la classe ExternalInterfaceProxy, la requête est convertie du format XML en un objet ExternalInterfaceCall, qui fournit les mêmes éléments, mais sous une forme plus accessible. La méthode SetReturnValue() du contrôle ActiveX est utilisée pour renvoyer un résultat de fonction au code ActionScript appelant ; là encore, le paramètre de résultat doit être converti au format XML utilisé par l’API externe.

La communication entre ActionScript et une application hébergeant le contrôle Active X Shockwave Flash nécessite un format XML spécifique qui servira à convertir les appels de fonction et les valeurs. Dans l’exemple Introvert IM C# example, la classe ExternalInterfaceProxy permet au code dans le formulaire de l’application d’agir directement sur des valeurs envoyées ou reçues d’ActionScript, et d’ignorer les détails du format XML utilisé par Flash Player. Pour cela, la classe ExternalInterfaceProxy utilise les méthodes de la classe ExternalInterfaceSerializer pour effectuer la conversion des messages XML en objets .NET. La classe ExternalInterfaceSerializer possède quatre méthodes publiques :

  • EncodeInvoke() : convertit un nom de fonction et une liste d’instruction C# ArrayList au format XML approprié.

  • EncodeResult() : convertit une valeur de résultat au format XML approprié.

  • DecodeInvoke() : décode un appel de fonction issu d’ActionScript. La propriété request de l’objet événement FlashCall est transmise à la méthode DecodeInvoke() et convertit l’appel en objet ExternalInterfaceCall.

  • DecodeResult() : décode la chaîne XML reçue comme résultat de l’appel d’une fonction ActionScript.

Ces méthodes convertissent des valeurs C# au format XML de l’API externe et décodent le XML en objets C#. Pour plus d’informations sur le format XML utilisé par Flash Player, voir Format XML de l’API externe.