Voorbeeld van externe API: communicatie tussen ActionScript en een bureaubladtoepassing die het ActiveX-besturingselement gebruikt

Flash Player 9 of hoger

In dit voorbeeld wordt het gebruik van de externe API getoond om te communiceren tussen ActionScript en een bureaubladtoepassing die gebruik maakt van ActiveX-besturing. In het voorbeeld wordt opnieuw gebruik gemaakt van de toepassing Introvert IM, waaronder de ActionScript-code en hetzelfde SWF-bestand; daarom wordt het gebruik van de externe API in ActionScript niet beschreven. Door de ervaring die u in het vorige voorbeeld hebt opgedaan, zult u het volgende voorbeeld beter begrijpen.

De bureaubladtoepassing in dit voorbeeld is geschreven in C# met behulp van Microsoft Visual Studio .NET. In deze beschrijving wordt de nadruk gelegd op specifieke technieken voor het werken met de externe API met behulp van het ActiveX-besturingselement. In dit voorbeeld wordt het volgende getoond:

  • ActionScript-functies aanroepen vanuit een bureaubladtoepassing die het Flash Player ActiveX-besturingselement host.

  • Functieaanroepen ontvangen vanuit ActionScript en deze verwerken in een ActiveX-container.

  • Een proxyklasse gebruiken om de details te verbergen van de XML-indeling met serienummering, die Flash Player gebruikt voor berichten die naar een ActiveX-container worden verzonden.

Zie www.adobe.com/go/learn_programmingAS3samples_flash_nl als u de toepassingsbestanden voor dit voorbeeld wilt downloaden. De C#-bestanden voor Introvert IM vindt u in de map Samples/IntrovertIM_CSharp. De toepassing bestaat uit de volgende bestanden:

Bestand

Beschrijving

AppForm.cs

Het hoofdtoepassingsbestand met de interface C# Windows Forms.

bin/Debug/IntrovertIMApp.swf

Het SWF-bestand dat door de toepassing is geladen.

ExternalInterfaceProxy/ExternalInterfaceProxy.cs

De klasse die het ActiveX-besturingselement voor communicatie met External Interface omvat. Het biedt mechanismen waarmee aanroepen vanuit ActionScript kunnen worden uitgevoerd en ontvangen.

ExternalInterfaceProxy/ExternalInterfaceSerializer.cs

De klasse die berichten in XML-indeling van Flash Player omzet in .NET-objecten.

ExternalInterfaceProxy/ExternalInterfaceEventArgs.cs

Dit bestand definieert twee C#-typen (klasse): een aangepaste delegate en een klasse met gebeurtenisargumenten, die worden gebruikt door de klasse ExternalInterfaceProxy om aan een listener een functieaanroep vanuit ActionScript te melden.

ExternalInterfaceProxy/ExternalInterfaceCall.cs

Deze klasse is een waardeobject dat een functieaanroep vertegenwoordigt vanuit ActionScript naar de ActiveX-container, met eigenschappen voor de functienaam en de parameters.

bin/Debug/IntrovertIMApp.swf

Het SWF-bestand dat door de toepassing is geladen.

obj/AxInterop.ShockwaveFlashObjects.dll,

obj/Interop.ShockwaveFlashObjects.dll

Wrappers gemaakt door Visual Studio .NET die nodig zijn om het ActiveX-besturingselement van de Flash Player (Adobe Shockwave® Flash) te benaderen vanuit de beheerde code.

Overzicht van de C#-toepassing Introvert IM

Deze voorbeeldtoepassing vertegenwoordigt twee instant messaging-clientprogramma’s (één binnen een SWF-bestand en een ander dat is gemaakt met Windows Forms) die met elkaar communiceren. De gebruikersinterface bevat een instantie van het ActiveX-besturingselement van Shockwave Flash, waarin het SWF-bestand met de ActionScript IM-client wordt geladen. De interface bevat ook verschillende tekstvelden die de Windows Forms IM-client vormen: een veld voor het invoeren van berichten (MessageText), een veld waarin de inhoud van de berichten tussen clients wordt weergegeven (Transcript) en een veld (Status) waarin de beschikbaarheid wordt weergegeven zoals in de SWF IM-client wordt ingesteld.

ActiveX-besturingselement van Shockwave Flash opnemen

Als u het ActiveX-besturingselement van Shockwave Flash in uw eigen Windows Forms-toepassing wilt opnemen, moet u dit eerst toevoegen aan de werkset Microsoft Visual Studio.

U kunt als volgt het besturingselement aan de werkset toevoegen:

  1. Open de werkset Visual Studio.

  2. Klik met de rechtermuisknop in het gedeelte Windows Forms in Visual Studio 2003 of in een willekeurig deel van Visual Studio 2005. Selecteer vanuit het contextmenu Add/Remove Items in Visual Studio 2003 (Choose Items... in Visual Studio 2005).

    Hierdoor wordt het dialoogvenster Customize Toolbox (2003)/Choose Toolbox Items (2005) geopend.

  3. Selecteer het tabblad COM Components, dat een lijst bevat met alle beschikbare COM-componenten op uw computer, waaronder het ActiveX-besturingselement van Flash Player.

  4. Blader naar het object Shockwave Flash en selecteer dit.

    Als dit item niet in de lijst voorkomt, controleer dan of het ActiveX-besturingselement van Flash Player op uw systeem is geïnstalleerd.

Communicatie tussen ActionScript en een ActiveX-container

Communicatie van de externe API met een ActiveX-containertoepassing werkt zoals communicatie met een webbrowser, maar met een belangrijk verschil. Wanneer ActionScript communiceert met een webbrowser, worden de functies voor de ontwikkelaar, zoals eerder beschreven, direct aangeroepen; de details over de indeling waarmee functieaanroepen en geretourneerde waarden tussen de speler en de browser worden doorgegeven, zijn verborgen. Wanneer de externe API echter wordt gebruikt om te communiceren met een ActiveX-containertoepassing, stuurt Flash Player berichten (functieaanroepen en geretourneerde waarden) in een specifieke XML-indeling naar de toepassing en gaat ervan uit dat de functieaanroepen en geretourneerde waarden van de containertoepassing gebruik maken van dezelfde XML-indeling. De ontwikkelaar van de containertoepassing van ActiveX moet codes schrijven waarmee functieaanroepen en geretourneerde waarden in de juiste indeling kunnen worden herkend en gemaakt.

Het C#-voorbeeld Introvert IM bevat een set klassen waarmee u indelingsberichten voorkomt; in plaats daarvan kunt u werken met standaardgegevenstypen wanneer u ActionScript-functies aanroept en functieaanroepen van ActionScript ontvangt. De klasse ExternalInterfaceProxy zorgt samen met andere hulpklassen voor deze functionaliteit en kan binnen elk .NET-project opnieuw worden gebruikt om communicatie met de externe API mogelijk te maken.

De volgende codesecties, die afkomstig zijn van het hoofdtoepassingsformulier (AppForm.cs), tonen de vereenvoudigde interactie, die wordt bereikt door gebruik te maken van de klasse 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); 
        ... 
    } 
    ...

De toepassing declareert en maakt een instantie ExternalInterfaceProxy met de naam proxy, die een verwijzing doorgeeft aan het ActiveX-besturingselement van Shockwave Flash dat zich in de gebruikersinterface (IntrovertIMApp) bevindt. Vervolgens registreert de code de methode proxy_ExternalInterfaceCall() om de gebeurtenis ExternalInterfaceCall van de proxy te ontvangen. Deze gebeurtenis wordt verzonden door de klasse ExternalInterfaceProxy wanneer een functieaanroep van de Flash Player wordt ontvangen. De C#-code ontvangt via een abonnement op deze gebeurtenis functieaanroepen vanuit ActionScript en reageert hierop.

Wanneer een functieaanroep uit ActionScript wordt ontvangen, ontvangt de ExternalInterfaceProxy-instantie (proxy) de aanroep, zet deze vanuit XML-indeling om en stuurt een melding naar de objecten die listeners zijn voor de gebeurtenis ExternalInterfaceCall van de proxy. Bij de klasse AppForm handelt de methode proxy_ExternalInterfaceCall() deze gebeurtenis als volgt af:

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

De methode wordt doorgegeven aan de instantie ExternalInterfaceCallEventArgs, die in dit voorbeeld de naam e heeft. Dit object heeft op zijn beurt een eigenschap FunctionCall die een instantie is van de klasse ExternalInterfaceCall.

Een instantie ExternalInterfaceCall is een eenvoudig waardeobject met twee eigenschappen. De eigenschap FunctionName bevat de functienaam die is opgegeven in de ActionScript-instructie ExternalInterface.Call(). Als er parameters in ActionScript worden toegevoegd, worden deze opgenomen in de eigenschap Arguments van het object ExternalInterfaceCall. De methode die de gebeurtenis afhandelt, is in dat geval een instructie switch die eenvoudig dient als regelaar van de gegevensstroom. De waarde van de eigenschap FunctionName (e.FunctionCall.FunctionName) bepaalt welke methode van de klasse AppForm wordt aangeroepen.

De vertakkingen van de instructie switch in de voorgaande codevoorbeeld tonen algemene scenario’s om een methode aan te roepen. Elke methode moet bijvoorbeeld ofwel een waarde naar ActionScript retourneren (de methodeaanroep isReady() bijvoorbeeld), ofwel null retourneren (zoals te zien is in de andere methodeaanroepen). Het benaderen van parameters die vanuit ActionScript zijn doorgegeven, wordt getoond in de methodeaanroep newMessage() (waarbij een parameter e.FunctionCall.Arguments[0] wordt doorgegeven, het eerste element van de array Arguments).

Het aanroepen van een ActionScript-functie vanuit C# met behulp van de klasse ExternalInterfaceProxy is nog eenvoudiger dan het ontvangen van een functieaanroep vanuit ActionScript. Om een ActionScript-functie aan te roepen, gebruikt u de methode Call() van de instantie ExternalInterfaceProxy als volgt:

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

Zoals uit dit voorbeeld blijkt, lijkt de methode Call() van de klasse ExternalInterfaceProxy sterk op het equivalent ActionScript, ExternalInterface.Call(). De eerste parameter is een tekenreeks, de naam van de aan te roepen functie. Aanvullende parameters (hier niet getoond) worden doorgegeven aan de ActionScript-functie. Als de ActionScript-functie een waarde retourneert, wordt deze waarde geretourneerd door de methode Call() (zoals in het vorige voorbeeld).

In de klasse ExternalInterfaceProxy

Wellicht is het gebruik van een proxywrapper rond het ActiveX-besturingselement niet altijd praktisch, of wilt u liever zelf een proxyklasse schrijven (bijvoorbeeld in een andere programmeertaal of voor een ander platform). Hoewel niet alle details voor het maken van een proxy hier worden beschreven, is het leerzaam wanneer u weet hoe de proxyklasse in dit voorbeeld werkt.

U gebruikt de methode CallFunction() van het ActiveX-besturingselement van Shockwave Flash om een ActionScript-functie aan te roepen met behulp van de externe API vanuit de ActiveX-container. Dit wordt getoond in dit fragment van de methode Call() van de klasse ExternalInterfaceProxy:

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

In dit codefragment is _flashControl het ActiveX-besturingselement van Shockwave Flash. ActionScript-functieaanroepen worden uitgevoerd met de methode CallFunction(). In deze methode wordt gebruik gemaakt van een parameter (request in dit voorbeeld), die een tekenreeks vormt bestaande uit instructies in XML-indeling met de naam van de aan te roepen ActionScript-functie en parameters. Waarden die worden geretourneerd van ActionScript worden gecodeerd als een tekenreeks in XML-indeling en teruggestuurd als de geretourneerde waarde van de aanroep CallFunction(). In dit voorbeeld wordt de XML-tekenreeks opgeslagen in de variabele response.

Het ontvangen van een functieaanroep vanuit ActionScript is een proces dat uit verschillende stappen bestaat. Functieaanroepen van ActionScript zorgen ervoor dat het ActiveX-besturingselement van Shockwave Flash de gebeurtenis FlashCall verzendt, zodat een klasse (bijvoorbeeld de klasse ExternalInterfaceProxy) die bedoeld is voor het ontvangen van aanroepen vanuit een SWF-bestand een handler voor die gebeurtenis moet definiëren. In de klasse ExternalInterfaceProxy heeft de functie van de gebeurtenishandler de naam _flashControl_FlashCall(); deze wordt geregistreerd om als volgt te luisteren naar de gebeurtenis in de klassenconstructor:

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

Het gebeurtenisobject (e) heeft een eigenschap request (e.request) die gevormd wordt door een tekenreeks bestaande uit informatie over de functieaanroep, zoals de functienaam en parameters in XML-indeling. De container kan aan de hand van deze informatie bepalen welke code moet worden uitgevoerd. In de klasse ExternalInterfaceProxy wordt de aanvraag omgezet van XML-indeling in een object ExternalInterfaceCall, dat dezelfde informatie in een meer toegankelijke vorm aanbiedt. De methode SetReturnValue() van het ActiveX-besturingselement wordt gebruikt om een functieresultaat te retourneren naar de ActionScript-aanroeper; ook hier geldt dat de resultatenparameter met de externe API moet worden gecodeerd in XML-indeling.

Bij communicatie tussen ActionScript en een toepassing die het ActiveX-besturingselement voor Shockwave Flash host, wordt gebruik gemaakt van een specifieke XML-indeling om functieaanroepen en waarden te coderen. In het C#-voorbeeld Introvert IM zorgt de klasse ExternalInterfaceProxy ervoor dat de code in het toepassingsformulier direct op de waarden kan worden uitgevoerd, die worden verzonden naar of ontvangen door ActionScript, en negeert de details van de XML-indeling die door Flash Player worden gebruikt. Hiervoor gebruikt de klasse ExternalInterfaceProxy de methoden van de klasse ExternalInterfaceSerializer om de XML-berichten te vertalen naar .NET-objecten. De klasse ExternalInterfaceSerializer beschikt over vier methoden van het type public:

  • EncodeInvoke(): codeert een functienaam en een ArrayList met argumenten in C# in de juiste XML-indeling.

  • EncodeResult(): codeert een resultaatwaarde in de juiste XML-indeling.

  • DecodeInvoke(): decodeert een functieaanroep vanuit ActionScript. De eigenschap request van het gebeurtenisobject FlashCall wordt doorgegeven aan de methode DecodeInvoke(); deze vertaalt de aanroep naar een object ExternalInterfaceCall.

  • DecodeResult(): decodeert de ontvangen XML als het resultaat van het aanroepen van een ActionScript-functie.

Deze methoden coderen C#-waarden in de XML-indeling van de externe API’s en decoderen de XML in C#-objecten. Zie XML-indeling van externe API voor meer informatie over de XML-indeling die in Flash Player wordt gebruikt.