Przykład użycia zewnętrznego interfejsu API: komunikacja między kodem ActionScript a aplikacją lokalną, która wykorzystuje formant ActiveX

Flash Player 9 i nowsze wersje

Ten przykład demonstruje użycie zewnętrznego interfejsu API w celu komunikacji między kodem ActionScript a aplikacją, która korzysta z formantu ActiveX. W tym przykładzie ponownie wykorzystano aplikację Introvert IM, łącznie z kodem ActionScript oraz tym samym plikiem SWF — przykład nie przedstawia użycia zewnętrznego interfejsu API w kodzie ActionScript. Znajomość poprzedniego przykładu może w znacznym stopniu ułatwić zrozumieniu tego przykładu.

Aplikacja pulpitu w tym przykładzie została napisana w języku C# za pomocą programu Microsoft Visual Studio .NET. Głównym omawianym zagadnieniem są określone techniki pracy z zewnętrznym interfejsem API przy wykorzystaniu formantu ActiveX. Ten przykład prezentuje:

  • Wywoływanie funkcji ActionScript z aplikacji pulpitu, która obsługuje formant Flash Player ActiveX

  • Odbieranie wywołań funkcji z kodu ActionScript i przekazywanie ich do kontenera ActiveX

  • Korzystanie z klasy proxy w celu ukrywania szczegółów serializowego formatu XML, z którego korzysta program Flash Player dla komunikatów wysyłanych do kontenera ActiveX

Aby pobrać pliki tej przykładowej aplikacji, należy przejść na stronę www.adobe.com/go/learn_programmingAS3samples_flash_pl. Pliki C# aplikacji Introvert IM są dostępne w folderze Samples/IntrovertIM_CSharp. Aplikacja składa się z następujących plików:

File

Opis

AppForm.cs

Główny plik aplikacji z interfejsem C# Windows Forms.

bin/Debug/IntrovertIMApp.swf

Plik SWF ładowany przez aplikację.

ExternalInterfaceProxy/ExternalInterfaceProxy.cs

Klasa, która służy jako moduł opakowaniowy formantu ActiveX dla komunikacji interfejsu zewnętrznego. Udostępnia mechanizmy przeznaczone do wywoływania i odbierania wywołań z kodu ActionScript.

ExternalInterfaceProxy/ExternalInterfaceSerializer.cs

Klasa, która wykonuje zadanie konwersji komunikatów w formacie XML programu Flash Player na obiekty .NET.

ExternalInterfaceProxy/ExternalInterfaceEventArgs.cs

Plik definiuje dwa typy C# (klasy): niestandardową klasę delegate, oraz klasę argumentów zdarzeń, które są używane przez klasę ExternalInterfaceProxy w celu powiadamiania detektora o wywołaniu funkcji z kodu ActionScript.

ExternalInterfaceProxy/ExternalInterfaceCall.cs

Ta klasa jest obiektem wartości, który reprezentuje wywołanie funkcji z kodu ActionScript do kontenera ActiveX, zawiera właściwości dla parametrów i nazwy funkcji.

bin/Debug/IntrovertIMApp.swf

Plik SWF ładowany przez aplikację.

obj/AxInterop.ShockwaveFlashObjects.dll,

obj/Interop.ShockwaveFlashObjects.dll

Zespoły opakowaniowe tworzone przez Visual Studio .NET, które są wymagane do uzyskania dostępu do formantu ActiveX programu Flash Player (Adobe Shockwave® Flash) z kodu zarządzanego.

Przegląd aplikacji C# Introvert IM

Ta prosta aplikacji prezentuje dwa programy klienckie wiadomości błyskawicznych (jeden w pliku SWF, a druga do Windows Forms), które komunikują się ze sobą. Interfejs użytkownika zawiera instancję formantu Shockwave Flash ActiveX, do której zostaje załadowany plik SWF zawierający program kliencki IM ActionScript. Interfejs zawiera również kilka pól tekstowych, które tworzą klienta Windows Forms IM: pole do wprowadzania komunikatów (MessageText); pole, w którym wyświetlana jest transkrypcja komunikatów wysyłanych między klientami (Transcript) oraz trzecie pole (Status), w którym wyświetlany jest status dostępności ustawiony przez klienta SWF IM.

Dołączanie formantu Shockwave Flash ActiveX

W celu dołączenia formantu Shockwave Flash ActiveX do aplikacji Windows Forms należy najpierw dodać format do przybornika Microsoft Visual Studio Toolbox.

W celu dodania formantu do przybornika:

  1. Otwórz przybornik Visual Studio Toolbox.

  2. Kliknij prawym przyciskiem myszy sekcję Windows Forms w programie Visual Studio 2003 lub dowolną sekcję w programie Visual Studio 2005. W menu kontekstowego wybierz opcję Add/Remove Items (Visual Studio 2003) (Choose Items... w programie Visual Studio 2005).

    To spowoduje otwarcie okna dialogowego Customize Toolbox (2003)/Choose Toolbox Items (2005).

  3. Wybierz kartę COM Components, które zawiera wszystkie dostępne składniki COM z komputera, złącznie z formantem Flash Player ActiveX.

  4. Przewiń do obiektu Shockwave Flash Object i zaznacz go.

    Jeśli ten element nie jest dostępny na liście, upewnij się, że w systemie zainstalowany jest składnik Flash Player ActiveX.

Informacje o komunikacji ActionScript z kontenerem ActiveX

Komunikacja za pomocą zewnętrznego interfejsu API z aplikacją kontenera ActiveX działa jak komunikacja z przeglądarką sieci Web z jedną istotną różnicą. Zgodnie z wcześniejszym opisem — gdy kod ActionScript komunikuje się z przeglądarką sieci Web, wówczas z perspektywy programisty funkcje są wywoływane bezpośrednio; szczegóły tego, w jaki sposób wywołania i odpowiedzi na funkcje są formatowane do przekazywania między odtwarzaczem i przeglądarką są ukryte. Jednak gdy zewnętrzny interfejs API zostanie użyty do komunikacji z aplikacją kontenera ActiveX, program Flash Player wysyła komunikaty (wywołania funkcji i wartości zwracane) do aplikacji w określonym formacie XML oraz oczekuje, że wywołania funkcji i zwrotów wartości z aplikacji kontenera będą używały tego samego formatu XML. Programista aplikacji kontenera ActiveX musi napisać kod, który będzie rozumiał i tworzył wywołania funkcji i odpowiedzi w odpowiednim formacie.

Przykład Introvert IM C# zawiera zestaw klas, które umożliwiają uniknięcie wyświetlania komunikatów dotyczących formatowania; podczas wywoływania funkcji ActionScript i odbierania wywołań funkcji z ActionScript można korzystać ze standardowych typów danych. Taką możliwość zapewnia klasa ExternalInterfaceProxy wraz z innymi klasami pomocniczymi, które mogą być używane powtórnie w dowolnym projekcie .NET w celu ułatwienia komunikacji zewnętrznego interfejsu API.

Poniższe sekcje kodu, stanowiące części głównej aplikacji (AppForm.cs), prezentują uproszczoną interakcję, jaką można uzyskać za pomocą klasy 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); 
        ... 
    } 
    ...

Aplikacja deklaruje i tworzy instancję ExternalInterfaceProxy o nazwie proxy, przekazując odwołanie do formantu Shockwave Flash ActiveX, który znajduje się w interfejsie użytkownika (IntrovertIMApp). Następnie kod rejestruje metodę proxy_ExternalInterfaceCall() w celu odebrania zdarzenia ExternalInterfaceCall proxy. To zdarzenie jest wywoływane przez klasę ExternalInterfaceProxy, jeśli wywołanie funkcji pochodzi z programu Flash Player. Zasubskrybowanie do tego zdarzenia to sposób, w jaki kod C# odbiera wywołania funkcji z ActionScript o odpowiada na nie.

Jeśli wywołanie funkcji pochodzi z ActionScript, wówczas wywołanie odbiera instancja ExternalInterfaceProxy (proxy), konwertuje je z formatu XML, a następnie powiadamia obiekty, które są detektorami zdarzenia ExternalInterfaceCall proxy. W przypadku klasy AppForm zdarzenie obsługuje metoda proxy_ExternalInterfaceCall() w następujący sposób:

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

Do metody zostaje przekazana instancja ExternalInterfaceCallEventArgs, która w tym przykładzie ma nazwę e. Z kolei ten obiekt zawiera właściwość FunctionCall, która jest instancją klasy ExternalInterfaceCall.

Instancja ExternalInterfaceCall jest prostym obiektem wartości z dwiema właściwościami. Właściwość FunctionName zawiera nazwę funkcji określoną w instrukcji ExternalInterface.Call() ActionScript. Jeśli jakiekolwiek parametry zostaną dodane do ActionScript, te parametry zostaną uwzględnione we właściwości Arguments obiektu ExternalInterfaceCall. W takim przypadku metoda, która obsługuje to zdarzenie, jest prostą instrukcją switch, która działa jako menedżer ruchu. Wartość właściwości FunctionName (e.FunctionCall.FunctionName) określa metodę klasy AppForm, która jest wywoływana.

Odgałęzienia instrukcji switch w poprzednim fragmencie kodu obrazują typowe scenariusze wywołania metody. Na przykład: metoda musi zwrócić wartość do kodu ActionScript (np. wywołanie metody isReady()) — w przeciwnym wypadku powinna zwrócić null (jak w przypadku wywołań innych metod). Dostęp do parametrów przekazanych z ActionScript przedstawiono w wywołaniu metody newMessage() (która jest przekazywana wraz z parametrem e.FunctionCall.Arguments[0], który jest pierwszym elementem tablicy Arguments).

Wywołanie funkcji ActionScript z kodu C# za pomocą klasy ExternalInterfaceProxy jest nawet bardziej bezpośrednie niż odbieranie wywołania funkcji z kodu ActionScript. W celu wywołania funkcji ActionScript należy użyć metody Call() instancji ExternalInterfaceProxy, co przedstawiono poniżej:

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

Zgodnie z przykładem metoda Call() klasy ExternalInterfaceProxy jest bardzo podobna do jej odpowiednika w ActionScript — metody ExternalInterface.Call(). Pierwszy parametr jest ciągiem znaków — nazwą funkcji do wywołania. Wszystkie dodatkowe parametry (nie przedstawione) są również wprowadzane do funkcji ActionScript. Jeśli funkcja ActionScript zwraca wartość, ta wartość jest zwracana returned przez metodę Call() (co przedstawiono w poniższym przykładzie).

W klasie ExternalInterfaceProxy

Stosowanie dla formantu ActiveX modułu opakowaniowego proxy nie zawsze jest wskazane, chyba że użytkownik chce napisać własną klasę proxy (np. w innym języku programowania lub dla innej platformy docelowej). W niniejszej sekcji nie zostaną omówione wszystkie szczegóły tworzenia proxy, ale przykład przedstawia zasady wewnętrznego działania klasy proxy.

Metoda CallFunction() formantu Shockwave Flash ActiveX służy do wywołania funkcji ActionScript z kontenera ActiveX przy wykorzystaniu zewnętrznego interfejsu API. Zostało to przedstawione w poniższym fragmencie metody Call() klasy ExternalInterfaceProxy:

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

W tym fragmencie kodu _flashControl jest formantem Shockwave Flash ActiveX. Funkcja ActionScript jest wywoływana za pomocą metody CallFunction(). Ta metoda przyjmuje jeden parametr (w tym przykładzie request), który jest ciągiem znaków zawierającym instrukcje w formacie XML zawierające nazwę funkcji ActionScript przeznaczonej do wywołania oraz parametry. Każda wartość zwracana z kodu ActionScript jest w postaci ciągu znaków w formacie XML i jest wysyłana jako wartość zawracana wywołania CallFunction(). W tym przykładzie ciąg znaków XML jest przechowywany w zmiennej response.

Odbieranie wywołania funkcji z kodu ActionScript jest procesem wieloetapowym. Wywołania funkcji z kodu ActionScript sprawiają, że formant Shockwave Flash ActiveX wywołuje własne zdarzenie FlashCall, dlatego klasa (np. klasa ExternalInterfaceProxy), która będzie odbierać wywołania z pliku SWF powinna zawierać definicję modułu obsługi dla tego zdarzenia. W klasie ExternalInterfaceProxy funkcja modułu obsługi tego zdarzenia handler ma nazwę _flashControl_FlashCall() i jest zarejestrowana w celu wykrywania tego zdarzenia w konstruktorze klasy, w następujący sposób:

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

Obiekt zdarzenia (e) zawiera właściwość request (e.request), która jest ciągiem znaków zawierającym informacje o wywołaniu funkcji, takie jak nazwa i parametry funkcji — w formacie XML. Te informacje mogą zostać wykorzystane przez kontener w celu wybrania kodu do wykonania. W klasie ExternalInterfaceProxy żądanie zostaje przekształcone z formatu XML na obiekt ExternalInterfaceCall, który udostępnia te same informacje w bardziej dostępnej formie. Metoda SetReturnValue() formantu ActiveX służy do zwracania wyniku funkcji do wywołującego kodu ActionScript; ponownie parametr wyniku musi zostać zakodowany w formacie XML używanym przez zewnętrzny interfejs API.

W komunikacji między językiem ActionScript oraz aplikacją obsługującą formant Shockwave Flash ActiveX wykorzystywany jest konkretny format w celu kodowania wywołań i wartości funkcji. W przykładzie Introvert IM C# dzięki klasie ExternalInterfaceProxy kod w aplikacji może korzystać bezpośrednio z wartości wysyłanych do lub odbieranych z ActionScript oraz ignorować szczegóły formatu XML, z którego korzysta program Flash Player. W celu osiągnięcia tego celu klasa ExternalInterfaceProxy korzysta z metod klasy ExternalInterfaceSerializer w celu tłumaczenia komunikatów XML na obiekty .NET. Klasa ExternalInterfaceSerializer zawiera cztery metody publiczne:

  • EncodeInvoke(): koduje nazwę funkcji i obiekt C# ArrayList argumentów na odpowiedni format XML.

  • EncodeResult(): koduje wartość wynikową na odpowiedni format XML.

  • DecodeInvoke(): dekoduje funkcję z kodu ActionScript. Właściwość request obiektu zdarzenia FlashCall zostaje przekazana do metody DecodeInvoke() i tłumaczy wywołanie na obiekt ExternalInterfaceCall.

  • DecodeResult(): dekoduje dane XML odebrane w wyniku wywołania funkcji ActionScript.

Te metody kodują wartości C# na format XML zewnętrznego interfejsu API i dekodują XML na obiekty C#. Szczegółowe informacje na temat formatu XML używanego przez program Flash Player zawiera sekcja Format XML zewnętrznego interfejsu API.