Пример внешнего API: связь между ActionScript и приложением для настольных компьютеров, использующим элемент управления ActiveX

Flash Player 9 или более поздних версий

В этом примере демонстрируется использование внешнего API для связи между ActionScript и приложением для настольной системы, использующим элемент управления ActiveX. В этом примере повторно используется приложение Introvert IM, включая код ActionScript и даже тот же SWF-файл. Вследствие этого в нем не описывается применение внешнего API в ActionScript. Знакомство с предыдущим примером поможет понять и этот.

Приложение для настольной системы в этом примере написано на языке C# с помощью Microsoft Visual Studio .NET. Предметом обсуждения служат конкретные методы работы с внешним API с помощью элемента управления ActiveX. Этот пример предполагает следующее.

  • Вызов функций ActionScript из приложения для настольных систем, в котором содержится элемент управления Flash Player ActiveX

  • Получение вызовов функции из ActionScript и их обработка в контейнере ActiveX

  • Использование класса прокси-сервера для скрытия сведений об упорядоченном формате XML, который используется Flash Player для сообщений, отправленных в контейнер ActiveX

Получить файлы приложения для этого примера можно на странице www.adobe.com/go/learn_programmingAS3samples_flash_ru. Файлы Introvert IM C# находятся в папке Samples/IntrovertIM_CSharp. Приложение состоит из следующих файлов.

File

Описание

AppForm.cs

Основной файл приложения с интерфейсом C# Windows Forms.

bin/Debug/IntrovertIMApp.swf

SWF-файл, загруженный приложением.

ExternalInterfaceProxy/ExternalInterfaceProxy.cs

Класс, который служит упаковщиком элемента управления ActiveX для связи с внешним интерфейсом. Он обеспечивает механизмы для вызова и получения вызовов из ActionScript.

ExternalInterfaceProxy/ExternalInterfaceSerializer.cs

Класс, выполняющий задачу преобразования сообщений для Flash Player в формате XML в объекты .NET.

ExternalInterfaceProxy/ExternalInterfaceEventArgs.cs

Этот файл определяет два типа (класса) C#: заказной делегат и класс аргументов события, которые применяются классом ExternalInterfaceProxy, чтобы уведомить прослушиватель вызова функции из ActionScript.

ExternalInterfaceProxy/ExternalInterfaceCall.cs

Этот класс является объектом значения, представляющим вызов функции из ActionScript в контейнер ActiveX со свойствами для имени функции и параметров.

bin/Debug/IntrovertIMApp.swf

SWF-файл, загруженный приложением.

obj/AxInterop.ShockwaveFlashObjects.dll,

obj/Interop.ShockwaveFlashObjects.dll

Блоки упаковщика, созданные Visual Studio .NET, которые требуются для доступа к элементу управления ActiveX для Flash Player (Adobe Shockwave® Flash) из управляемого кода.

Обзор приложения Introvert IM на языке C#

Этот образец приложения представляет две клиентские программы для мгновенного обмена сообщениями (одна — в SWF-файле, а другая — встроена в Windows Forms), которые связаны между собой. Пользовательский интерфейс включает экземпляр элемента управления ActiveX для Shockwave Flash, в который загружается SWF-файл, содержащий клиент системы мгновенного обмена сообщениями на ActionScript. Этот интерфейс включает также несколько текстовых полей, имеющихся в клиенте системы мгновенного обмена сообщениями Windows Forms: поле для ввода сообщений (MessageText), другое поле, где показана расшифровка сообщений, отправленных от одного клиента другому (Transcript) и поле (Status), где указано состояние доступности, установленное в клиенте системы мгновенного обмена сообщениями для SWF.

Включение элемента управления ActiveX для Shockwave Flash

Чтобы включить элемент управления ActiveX для Shockwave Flash в собственное приложение Windows Forms, необходимо сначала добавить его на инструментальную панель (в Microsoft Visual Studio Toolbox).

Чтобы добавить элемент управления на инструментальную панель, выполните следующие действия.

  1. Откройте Visual Studio Toolbox.

  2. Щелкните правой кнопкой мыши раздел Windows Forms в Visual Studio 2003 или любой раздел в Visual Studio 2005. Выберите в контекстном меню «Добавить/удалить элементы» в Visual Studio 2003 («Выбрать элементы...» в Visual Studio 2005).

    Это приводит к открытию диалогового окна для настройки панели инструментов (2003) или диалогового окна для выбора элементов панели инструментов (2005).

  3. Выберите вкладку «COM Components», на которой перечислены все доступные компоненты COM на вашем компьютере, включая элемент управления ActiveX для Flash Player.

  4. Перейдите с помощью прокрутки к объекту Shockwave Flash и выделите его.

    Если этот элемент не перечислен, убедитесь в том, что элемент управления ActiveX для Flash Player установлен в компьютере.

Сведения о связи между ActionScript и контейнером ActiveX

Связь с использованием внешнего API с приложением контейнера ActiveX действует как связь с веб-обозревателем, имея одно важное отличие. Как описывалось ранее, когда ActionScript связывается с веб-обозревателем, то до тех пор, пока речь идет о разработчике, функции вызываются напрямую. Подробные сведения о форматах вызовов функции и ответах, передаваемых между проигрывателем и обозревателем, скрыты. Однако когда внешний API используется для связи с приложением контейнера ActiveX, Flash Player отправляет сообщения (вызовы функций и возвращаемые значения) в приложение в особом формате XML. При этом ожидается, что вызовы функций и возвращаемые значения в приложении контейнера будут использовать один и тот же формат XML. Разработчик приложения контейнера ActiveX должен написать код, который распознает и может создавать вызовы функций и ответы в соответствующем формате.

Пример Introvert IM C# включает набор классов, позволяющих избежать сообщений форматирования. Вместо этого можно работать со стандартными типами данных при вызове функций ActionScript и получении вызовов функций из ActionScript. Класс ExternalInterfaceProxy вместе с другими вспомогательными классами обеспечивает эту функциональную возможность, и его можно повторно использовать в любом проекте .NET, чтобы упростить связь с внешним 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); 
        ... 
    } 
    ...

Это приложение объявляет и создает экземпляр ExternalInterfaceProxy с именем proxy, передавая ссылку на элемент управления ActiveX для Shockwave Flash, находящийся в пользовательском интерфейсе (IntrovertIMApp). Затем код регистрирует метод proxy_ExternalInterfaceCall() для получения события ExternalInterfaceCall прокси-сервера. Это событие отправляется классом ExternalInterfaceProxy, когда вызов функции поступает в Flash Player. С помощью подписки на это событие код 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 в этом примере. Этот объект в свою очередь имеет свойство FunctionCall, которое является экземпляром класса ExternalInterfaceCall.

Экземпляр ExternalInterfaceCall — это простой объект значения, имеющий два свойства. Свойство FunctionName содержит имя функции, указанное в инструкции ActionScript ExternalInterface.Call(). Если в ActionScript добавлены другие параметры, то они включены в свойство Arguments объекта ExternalInterfaceCall. В данном случае метод, который обрабатывает событие, является просто инструкцией switch, которая выступает в роли диспетчера трафика. Значение свойства FunctionName (e.FunctionCall.FunctionName) определяет метод, вызываемый классом AppForm.

Ветви инструкции switch в предыдущем примере кода демонстрируют распространенные сценарии вызова метода. Например, любой метод должен возвращать значение в ActionScript (например, вызов метода isReady()) или возвращать null (как это происходит при вызовах других методов). Доступ к параметрам, переданным из ActionScript, продемонстрирован в вызове метода newMessage() (который передает параметр e.FunctionCall.Arguments[0], первый элемент массива Arguments).

Вызов функции ActionScript из C# с помощью класса ExternalInterfaceProxy является еще более прямолинейным, чем получение вызова функции из ActionScript. Чтобы вызвать функцию ActionScript, используется метод Call() экземпляра ExternalInterfaceProxy:

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

Как показано в данном примере, метод Call() класса ExternalInterfaceProxy очень похож на его эквивалент в ActionScript, метод ExternalInterface.Call(). Первый параметр — это строка с именем вызываемой функции. Какие-либо дополнительные параметры (не показанные здесь) передаются функции ActionScript. Если функция ActionScript возвращает значение, то оно возвращается методом Call() (как показано в предыдущем примере).

Подробно о классе ExternalInterfaceProxy

Использование упаковщика прокси-сервера с элементом управления ActiveX не всегда практично. Возможно, что вы захотите написать свой собственный класс прокси-сервера (например, на другом языке программирования или нацеленный на другую платформу). Хотя здесь будут поясняться не все подробности создания прокси-сервера, полезно разобраться во внутреннем механизме класса прокси-сервера в этом примере.

Метод CallFunction() элемента управления ActiveX для Shockwave Flash применяется для вывода функции ActionScript из контейнера ActiveX с помощью внешнего API. Это показано в данном фрагменте метода Call(), принадлежащего классу ExternalInterfaceProxy:

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

В данном фрагменте кода _flashControl является элементом управления ActiveX для Shockwave Flash. Вызовы функции ActionScript выполняются с использованием метода CallFunction(). Этот метод имеет один параметр (request в этом примере), который представляет собой строку, содержащую инструкции в формате XML, включая имя вызываемой функции ActionScript и любые параметры. Любое значение, возвращенное ActionScript, кодируется в виде строки в формате XML и отправляется назад в качестве значения, возвращаемого при вызове CallFunction(). В данном примере эта строка XML сохраняется в переменной response.

Получение вызова функции из ActionScript происходит в несколько этапов. Вызовы функции из ActionScript приводят к тому, что элемент управления ActiveX для Shockwave Flash отправляет свое событие FlashCall, чтобы класс (например, класс ExternalInterfaceProxy), который выбран для получения вызовов из SWF-файла, требовал определить обработчик данного события. В классе 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, который предоставляет ту же информацию в более доступной форме. Метод SetReturnValue() элемента управления ActiveX возвращает результат функции вызывающему коду ActionScript. Затем параметр результата должен быть переведен в формат XML, использованный внешним API.

Связь между ActionScript и приложением, в котором находится элемент управления ActiveX для Shockwave Flash, реализуется с помощью формата XML, используемого для кодирования вызовов функции и значений. В примере Introvert IM C# класс ExternalInterfaceProxy позволяет коду в форме приложения напрямую работать со значениями, отправленными в ActionScript или полученными из него, игнорируя сведения о формате XML, которые использует Flash Player. Для этого класс ExternalInterfaceProxy прибегает к методам класса ExternalInterfaceSerializer, чтобы фактически преобразовать сообщения XML в объекты .NET. Класс ExternalInterfaceSerializer имеет четыре общедоступных метода.

  • EncodeInvoke(): кодирует имя функции и ArrayList с аргументами в C# в соответствующий формат XML.

  • EncodeResult(): кодирует значение результата в соответствующий формат XML.

  • DecodeInvoke(): декодирует вызов функции из ActionScript. Свойство request объекта события FlashCall передается методу DecodeInvoke(), который переводит этот вызов в объект ExternalInterfaceCall.

  • DecodeResult(): декодирует XML, полученный в результате вызова функции ActionScript.

Эти методы кодируют значения C# в формат XML внешнего API и декодируют XML в объекты C#. Сведения о формате XML, используемом Flash Player, см. в разделе «Формат XML внешнего API».