Beispiel für externe API: Kommunikation zwischen ActionScript und einer Desktopanwendung, die das ActiveX-Steuerelement verwendetFlash Player 9 und höher In diesem Beispiel wird die Verwendung der externen API für den Datenaustausch zwischen ActionScript und einer Desktopanwendung mit einem ActiveX-Steuerelement veranschaulicht. In dem Beispiel wird weiterhin die Anwendung „Introvert IM“ verwendet, einschließlich des ActionScript-Codes und sogar derselben SWF-Datei. Deshalb wird auf eine erneute Beschreibung des Einsatzes der externen API in ActionScript verzichtet. Wenn Sie mit dem vorangegangenen Beispiel vertraut sind, erleichtert dies das Verständnis des aktuellen Beispiels. Die Desktopanwendung in diesem Beispiel wurde mit Microsoft Visual Studio.NET in C# programmiert. Der Schwerpunkt liegt auf den spezifischen Techniken zur Verwendung der externen API mit dem ActiveX-Steuerelement. In diesem Beispiel wird Folgendes veranschaulicht:
Die Anwendungsdateien für dieses Beispiel finden Sie unter www.adobe.com/go/learn_programmingAS3samples_flash_de. Die C#-Dateien der Anwendung „Introvert IM“ befinden sich im Ordner „Samples/IntrovertIM_CSharp“. Die Anwendung umfasst die folgenden Dateien:
Überblick über die C#-Anwendung „Introvert IM“Diese Beispielanwendung stellt zwei Instant Messaging-Clientprogramme (eine in einer SWF-Datei und die andere mit Windows Forms erstellt) dar, die miteinander kommunizieren. Zur Benutzeroberfläche gehört eine Instanz des Shockwave Flash-ActiveX-Steuerelements, in die die SWF-Datei geladen wird, die den ActionScript-IM-Client enthält. Die Benutzeroberfläche umfasst auch mehrere Textfelder, die den Windows Forms-IM-Client bilden: ein Feld zum Eingeben von Nachrichten (MessageText), ein weiteres zum Anzeigen des Mitschnitts der zwischen den beiden Clients ausgetauschten Nachrichten (Transcript) und ein drittes (Status), das den im SWF-IM-Client festgelegten Verfügbarkeitsstatus angibt. Einfügen des Shockwave Flash-ActiveX-SteuerelementsUm das Shockwave Flash-ActiveX-Steuerelement in die Windows Forms-Anwendung aufnehmen zu können, müssen Sie es zuerst zur Toolbox von Microsoft Visual Studio hinzufügen. So fügen Sie das Steuerelement zur Toolbox hinzu:
Kommunikation zwischen ActionScript und dem ActiveX-ContainerDie Kommunikation mit einer ActiveX-Containeranwendung über die externe API entspricht der Kommunikation mit einem Webbrowser, jedoch mit einem wichtigen Unterschied. Wie bereits beschrieben, werden bei der Kommunikation von ActionScript mit einem Webbrowser – zumindest soweit es Entwickler betrifft – die Funktionen direkt aufgerufen. Die Details der Formatierung von zwischen Player und Browser übergebenen Funktionsaufrufen und Rückgabewerten sind verborgen. Wenn die externe API jedoch für den Datenaustausch mit einer ActiveX-Containeranwendung eingesetzt wird, werden in Flash Player Nachrichten (Funktionsaufrufe und Rückgabewerte) in einem speziellen XML-Format an die Anwendung gesendet. Bei Funktionsaufrufen und Rückgabewerten aus der Containeranwendung wird dasselbe XML-Format erwartet. Entwickler der ActiveX-Containeranwendung müssen Code programmieren, mit dem dieses Format gelesen werden kann und mit dem Funktionsaufrufe und Rückgabewerte entsprechend formatiert werden. Die C#-Beispielanwendung „Introvert IM“ enthält eine Reihe von Klassen, mit denen Sie die Formatierung von Nachrichten vermeiden können. Stattdessen können Sie beim Aufrufen von ActionScript-Funktionen und beim Empfangen von Funktionsaufrufen aus ActionScript die Standarddatentypen verwenden. Diese Funktionalität wird von der ExternalInterfaceProxy-Klasse und anderen unterstützenden Klassen bereitgestellt. Sie kann in allen .NET-Projekten eingesetzt werden, um die Kommunikation über die externe API zu erleichtern. In den folgenden Codeabschnitten, die einen Auszug aus dem Hauptformular der Anwendung (AppForm.cs) darstellen, wird die vereinfachte Interaktion demonstriert, die mithilfe der ExternalInterfaceProxy-Klasse erreicht wird: 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);
...
}
...
In der Anwendung wird eine ExternalInterfaceProxy-Instanz mit dem Namen proxy deklariert und erstellt sowie ein Verweis auf das Shockwave Flash-ActiveX-Steuerelement übergeben, das sich in der Benutzeroberfläche (IntrovertIMApp) befindet. Anschließend wird die proxy_ExternalInterfaceCall()-Methode für den Empfang des vom Proxy gesendeten ExternalInterfaceCall-Ereignisses registriert. Dieses Ereignis wird von der ExternalInterfaceProxy-Klasse ausgelöst, wenn ein Funktionsaufruf aus Flash Player erfolgt. Durch Registrieren für dieses Ereignis im C#-Code werden von ActionScript stammende Funktionsaufrufe empfangen, und es kann auf sie reagiert werden. Wenn ein von ActionScript ausgehender Funktionsaufruf eintrifft, empfängt die ExternalInterfaceProxy-Instanz (proxy) den Aufruf, konvertiert ihn aus dem XML-Format und benachrichtigt die Objekte, die Listener für das ExternalInterfaceCall-Ereignis der Proxy-Klasse registriert haben. Im Fall der AppForm-Klasse wird das Ereignis wie folgt mit der proxy_ExternalInterfaceCall()-Methode verarbeitet: /// <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;
}
}
...
In diesem Beispiel wird eine ExternalInterfaceCallEventArgs-Instanz mit dem Namen e an die Methode übergeben. Dieses Objekt hat wiederum eine FunctionCall-Eigenschaft, die eine Instanz der ExternalInterfaceCall-Klasse ist. Eine ExternalInterfaceCall-Instanz ist ein einfaches Wertobjekt mit zwei Eigenschaften. Die FunctionName-Eigenschaft enthält den in der ActionScript-Anweisung ExternalInterface.Call() angegebenen Funktionsnamen. Wenn in ActionScript Parameter hinzugefügt wurden, werden diese in der Arguments-Eigenschaft des ExternalInterfaceCall-Objekts abgelegt. In diesem Fall besteht die Methode zur Ereignisverarbeitung einfach aus einer switch-Anweisung, die wie ein Verteiler funktioniert. Der Wert der FunctionName-Eigenschaft (e.FunctionCall.FunctionName) gibt an, welche Methode der AppForm-Klasse aufgerufen wird. Die Verzweigungen der switch-Anweisung im vorangegangenen Codebeispiel veranschaulichen häufige Aufrufszenarien. Beispielsweise muss jede Methode entweder einen Wert an ActionScript zurückgeben (z. B. beim Aufruf der isReady()-Methode) oder andernfalls null (wie in den anderen Methodenaufrufen dargestellt). Der Zugriff auf von ActionScript übergebene Parameter wird beim Aufruf der newMessage()-Methode demonstriert (bei dem der Parameter e.FunctionCall.Arguments[0] übergeben wird, das erste Element des Arrays Arguments). Das Aufrufen einer ActionScript-Funktion aus C# mithilfe der ExternalInterfaceProxy-Klasse ist sogar noch einfacher als das Empfangen von Funktionsaufrufen aus ActionScript. Verwenden Sie zum Aufrufen einer ActionScript-Funktion wie folgt die Call()-Methode der ExternalInterfaceProxy-Instanz: /// <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");
}
...
}
Wie dieses Beispiel veranschaulicht, ähnelt die Call()-Methode der ExternalInterfaceProxy-Klasse sehr dem ActionScript-Gegenstück ExternalInterface.Call(). Der erste Parameter ist ein String: der Name der aufzurufenden Funktion. Alle weiteren Parameter (im Beispiel nicht dargestellt) werden ebenfalls an die ActionScript-Funktion übergeben. Wenn die ActionScript-Funktion einen Wert zurückgibt, wird dieser von der Call()-Methode zurückgegeben (wie im vorangegangenen Beispiel dargestellt). Details der ExternalInterfaceProxy-KlasseDie Verwendung eines Proxy-Wrappers um das ActiveX-Steuerelement ist nicht immer praktikabel, oder Sie möchten vielleicht eine eigene Proxy-Klasse programmieren (beispielsweise in einer anderen Programmiersprache oder für eine andere Plattform). Obwohl an dieser Stelle nicht auf alle Details zum Erstellen einer Proxy-Klasse eingegangen wird, ist es sicherlich lehrreich, den internen Aufbau der in diesem Beispiel verwendeten Proxy-Klasse zu verstehen. Sie verwenden die CallFunction()-Methode des Shockwave Flash-ActiveX-Steuerelements, um mithilfe der externen API eine ActionScript-Funktion aus dem ActiveX-Container aufzurufen. Dies ist im folgenden Auszug aus der Call()-Methode der ExternalInterfaceProxy-Klasse dargestellt: // Call an ActionScript function on the SWF in "_flashControl", // which is a Shockwave Flash ActiveX control. string response = _flashControl.CallFunction(request); Im Codeauszug ist _flashControl das Shockwave Flash-ActiveX-Steuerelement. ActionScript-Funktionsaufrufe erfolgen mit der CallFunction()-Methode. Diese Methode erwartet einen Parameter (im Beispiel request). Dabei handelt es sich um einen String mit XML-formatierten Anweisungen, aus dem der Name der aufzurufenden ActionScript-Funktion und etwaige Parameter hervorgehen. Ein gegebenenfalls von ActionScript zurückgegebener Wert wird als XML-formatierter String kodiert und als Rückgabewert des CallFunction()-Aufrufs zurückgesendet. In diesem Beispiel wird dieser XML-String in der Variablen response gespeichert. Das Empfangen eines Funktionsaufrufs aus ActionScript besteht aus mehreren Schritten. Durch Funktionsaufrufe aus ActionScript wird mit dem Shockwave Flash-ActiveX-Steuerelement ein FlashCall-Ereignis ausgelöst. Bei einer Klasse (beispielsweise der ExternalInterfaceProxy-Klasse), die Aufrufe aus einer SWF-Datei empfangen soll, muss deshalb eine Ereignisprozedur für dieses Ereignis definiert werden. Bei der ExternalInterfaceProxy-Klasse trägt die Ereignisprozedurfunktion den Namen _flashControl_FlashCall() und wird im Klassenkonstruktor wie folgt als Listener für das Ereignis registriert: 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);
}
Das Ereignisobjekt (e) hat eine request-Eigenschaft (e.request). Dabei handelt es sich um einen String, der im XML-Format Informationen über den Funktionsaufruf, z. B. den Funktionsnamen und die Parameter, enthält. Mithilfe dieser Informationen kann im Container ermittelt werden, welcher Code ausgeführt werden soll. Mit der ExternalInterfaceProxy-Klasse wird die Anforderung aus dem XML-Format in ein ExternalInterfaceCall-Objekt konvertiert, das dieselben Informationen in einer besser zugänglichen Form bereitstellt. Mithilfe der SetReturnValue()-Methode des ActiveX-Steuerelements wird ein Funktionsergebnis an den aufrufenden ActionScript-Code zurückgegeben. Wieder muss der Ergebniswert in das von der externen API verwendete XML-Format kodiert werden. Bei der Kommunikation zwischen ActionScript und einer Anwendung, in der ein Shockwave Flash-ActiveX-Steuerelement ausgeführt wird, wird zum Kodieren der Funktionsaufrufe und Rückgabewerte ein spezielles XML-Format verwendet. In der C#-Beispielanwendung „Introvert IM“ ermöglicht es die ExternalInterfaceProxy-Klasse, dass im Code des Anwendungsformulars direkt auf die an ActionScript gesendeten oder von ActionScript empfangenen Werte zugegriffen werden kann und die Details des von Flash Player verwendeten XML-Formats nicht beachtet werden müssen. Dazu werden in der ExternalInterfaceProxy-Klasse die Methoden der ExternalInterfaceSerializer-Klasse verwendet, um die XML-Nachrichten in .NET-Objekte umzuwandeln. Die ExternalInterfaceSerializer-Klasse verfügt über vier öffentliche Methoden:
Mit diesen Methoden werden C#-Werte in das XML-Format der externen API kodiert bzw. XML-Werte in C#-Objekte dekodiert. Weitere Informationen zum vom Flash Player verwendeten XML-Format finden Sie unter XML-Format der externen API. |
|