bojolais (bojolais) wrote,

Simple C# and Flash interop

I've recently promised Larry I'd share new insights about interoperability between C# code and Flash.

Flash is often assumed to be only a toy for web designers, but it's actually a very powerfully programmable visualization tool in the hands of a technically capable artist. In the not-quite-immediate future for Windows programmers, the Windows Presentation Foundation promises to obsolete Flash for most Windows-native applications, but WPF currently exists only as technology previews. You have plenty of time to get dangerous with a little Flash in your .NET before WPF is a viable alternative.

There are two primary strategies for interoperability with Flash, and the new External API is what I'll show here (the alternative involving some simple socket communication between a .NET app and an out-of-process Flash player). Essentially, you can embed a ActiveX Flash player into a Windows form, load Flash code ("movies") into the player, then set variables or invoke functions with single method calls in the flash code from C#. Hook up a delegate to one of the Flash player's events, and you can receive communcation back from the Flash code. It's that simple, as you can see in this post by Gabe Wishnie.

Most complicated was simply getting the Flash control to work in Visual Studio 2005. Basically, it doesn't automatically create the interop DLL properly, but placing the interop DLL generated by VS.NET 2003 into your project's obj directory is a quick work-around. Read more about this work-around on Mark Dryden's site.

In the Forms designer in VS 2005, right-click in the Toolbox and select "Choose items" to add the "Shockwave Flash Object" COM component (assuming you've installed Flash and have the control registered). Next, drag the player control to your form. To begin interacting with Flash, first load your Flash code into the control:
    this.yourFlashControl.LoadMovie(0,
        Application.StartupPath + "\\yourFlashMovie.swf");


To set a variable in the Flash code named "myFlashVariable" to the value "Hello Flash", just call:
    this.yourFlashControl.SetVariable("myFlashVariable", "Hello Flash!");


To invoke the Flash function "myFlashFunction" (which takes a string and a number as input arguments) assemble the following XML string:
    <invoke name="myFlashFunction" returntype="xml">
        <arguments>
            <string>Hello Flash!</string>
            <number>42</number>
        </arguments>
    </invoke>    


Pass this string into the following method on the Flash player control:
    this.yourFlashControl.CallFunction(yourXmlInvokeString);


That is it. You can now invoke Flash functions.

To receive method invocations from Flash code, implement a method with the following signature:
    void FlashCallEventHandler(object,
        AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEvent)


Register a delegate to this method with the FlashCall event to hook this up. Whenever the External API is used within Flash to call an external method, your delegate will be invoked. The AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEvent's request property will consist of an XML string in the same format we passed to Flash earlier, so simply parse out the intended method name and input arguments and act upon them as you wish.
    private yourInitMethodOfChoice()
    {
        this.yourFlashControl.LoadMovie(0, Application.StartupPath +
            "\\yourFlashMovie.swf");
        this.yourFlashControl.FlashCall +=
            new AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEventHandler(
                this.FlashCallEventHandler);
    }

    private void FlashCallEventHandler(object sender,
        AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEvent e)
    {
        // inside here, just parse e.request.  Some validation is recommended, but
        // using reflection to directly invoke methods requested via Flash is very
        // simple to implement.
    }
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded  

  • 9 comments