In this article i will show you how you can write a wrapper in c# for swf files. I will cover how you embed the Flash ActiveX control in your c# project and how the communication between c# and your swf file works. I assume that you are a flash developer that has zero knowledge of c# or visual studio (as that is what i`m). You will find out that c# is not much different than Actionscript.
First you`ll need Visual Studio. For this article I used Visual C# Express which is the free version of VisualStudio 2005. You can download it here:
For the communication between the swf file and the c# wrapper I use the external interface feature which was introduced to the swf specification version 8. So you`ll need something that produces swf file version 8 or above. For this article I used Flex Builder. If you don`t have Flex builder you can download a trial here:
I will try to go through the process step by step but this involves that you switch from Flexbuilder to VisualStudio from time to time so just keep them both open and ready.
First we`re going to set up a Visual Studio Project. Open up Visual Studio and create a new project (File >> New Project).
In the Dialog that appears select the first entry (Windows Application) and name your project FlashCommunication.
Visual Studio will now open up a new project with a blank Windows Form. Now we need to get the Flash ActiveX control into our project. To do this open up the toolbox (View >> Toolbox). You should now have the toolbox open on the left side.
Right Click on the first entry (“Alle Windows Forms”) and choose “Elements auswählen”.
In the following dialog select the COM Tab and locate the Shockwave Flash Object. Select it and click OK.
You should now have a new Element in your Toolbox called Flash Shockwave Object. Select it and drag it into the Form Window. If everything works fine you are lucky. I had some problems at this point which seemed to be related to a bug in related to VisualStudio 2005. It does not appear in VisualStudio 2003. In my case I got the error message 'Failed to import the ActiveX control. Please ensure it is properly registered' After some Google research I found a workaround for this. Read about it here:
The files that are mentioned in the article are included in the Visual C# Express project files.
If you have any questions about this workaround feel free to mail me at: firstname.lastname@example.org
Now we`re going to add some more Elements to the interface. Drag a TextBox and a Button to the stage so that it looks something like this (Figure 5.):
Now change some of the properties of the elements in the Property Inspector which should be located on the right side of your project. Change the Name property of the Flash Object to flashElement. Set the Name property of the TextBox to be response_tx and make it multiline. Now change the Button Text to “Say Hello to Flash”, and set the instance name to send_btn.
Locate the Event Tab in the Property Inspector for the Button and enter “onSendToFlash” for the Click event (Figure 6.).
Visual C# Express will automatically generate the code of this method and register it as an event handler for the button`s click event.
Now we need to set up the ActiveX control to listen for function calls from the swf. Select the ActiveX control and click on the events tab in the property inspector. Search for the event calles FlashCall. Select this event write in the text box "onFlashCall". (See Figure 7).
Visual C# Express has now automatically added a callback function called onFlashCall and a function onSendToFlash in the Form1.cs class (see Figure 8). The function onFlashCall will be called everytime a call via ExternalInterface is made from the swf and the function onSendToFlash is triggered everytime we click the button. Later we will here place the code to call function within flash/flex.
Now we have everything in place. All we need now is a swf file and than we can add the code for the communication. Leave your Visual C# Express Project alone for now and open up Flexbuilder.
Settin Up Your Flexbuilder Project:
Open up Flexbuilder and set up a Flex Project. Select File>> New >> Flex Project. In the Dialog that pops up select Basic Flex Project and click Next.
In the next dialog screen enter the name of the project (see Figure 10) and proceed to the next screen.
Now there is an important thing. In this dialog you have to change the default output folder to point to your Visual C# Express Project. Click on the browse button and locate the bin/Debug folder within your C# project (see Figure 11). Later we have to load the swf that flexbuilder produces into the ActiveX Container. Having the swf within our C# project folder will make it easier to locate it from there.
Now click the Finish button. Now locate the FlashCommunication.mxml file within your project, select it and switch to design view.
Here quickly lay out a TextArea component and a button component roughly like shown in the next image (Figure 12).
Now switch to design view. You see that Flexbuilder has generated the markup for our controls. Now we are going to add an event handler to our button control. First we create a <mx:Script> tag. within this we write the callback function (onSend), that gets called when the button gets pressed. We send set the click attribute of our button component to point to this function (see Figure 13).
We now have a basic swf file that we can load into the ActiveX control in our C# project. Switch to the Visual C# Express project and create a new function called loadFlashMovie right after the Constructor of the Form1 class. Remember that we configured Flexbuilder to export the swf file into the bin/Debug folder of our C# project. This is the place were Visual C# Express builds the project while testing it from the ide. To get this path we use:
String swfPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "FlashCommunication.swf";
In order to use the Directory class we also have to import the Package System.IO. Than we can load the file into the ActiveX control with: this.flashElement.LoadMovie(0, swfPath);
Test the project and if everything is correct you should see a result similiar to Figure 15
Now we are just two small steps away from diplaying messages from flash in the TextBox in our C# project. Locate the function onFlashCall that was created by Visual C# Express and add this line to it: this.response_tx.Text = e.request;
The parameter e of this function is of the type _IShockwaveFlashEvents_FlashCallEvent. It has a property which holds an xml formatted string with the information send from flash/flex. For this article we simply write this information into our TextBox (see Figure 16)
Now we need to extend the FlashCommunication.mxml file to make an External Interface call. First import the class flash.external.ExternalInterface. Than in the onSend function make the actual External interface call. The first argument is the name of a function and the second argument is a parameter we want to pass to that function (see Figure 17).
Now compile the Flex project and switch back to Visual C# Express.
Run the C# project and click the Say Hello to C# button. You should get the following result (Figure 18):
You see that we get an xml string that describes the call from flex. The xml is a detailed description of the method the swf wants to call and it`s arguments. So flex is not really calling the function in C# it`s just telling us what functions it wants to call and which arguments it has. If we wanted to actually call this function we would have to write some kind of proxy that parses the xml and casts the arguments to C# types and than calls this function. I will go into detail about this an another article.
Now that we have enabled Flex to talk to C# and C# listen to Flex we need to make it work the other way around. The ActiveX Flash control has a function called CallFunction that expects a string as an argument. In this string we can describe a function and its arguments just the way we just saw it when flex called the function in C#. So if we want to call a function in the swf that is called onMessageFromC that has one argument a string, we would have to format the string like this:
<invoke name=\"onMessageFromC\"><arguments><string>Hello Flex!</string></arguments></invoke>
The whole call will be done in the button event handler (Figure 19)
Now we have to register this function to the ExternalInterface in Flexbuilder. To this i`ve added a function init() as a callback to the creationComplete Event of our application Tag. Within the init function i registered the function onMessageFromC and mapped it to the callback onMessageFromC (see Figure 20). Than i just added the result to the response_tx TextArea that we created earlier.
Compile the Flex project and test everything from Visual C# Express. You can see the result in Figure 21
This is an extremely simple example that just shows the two way communication process between a swf and a c# wrapper. The cool thing is that with this simple process you can do some powerful things. For example i created a project were i embeded the Microsoft speech recognition engine and than you could control a flex application with a microphone and just your voice!