Introduction

Flash is nice, but it is mainly used in the Web. How about embedding flash into your own applications AND transfer data from/to them?

I've found out that many have discussed this subject, but sometimes their method will mysteriously fail for a reason. Here is a fully functional and very simple project.

Background

This article assumes you are familiar with C++ and COM. Make sure you review these topics and also review my Win32 ActiveX article. You can also use MFC or ATL to insert the ActiveX control without messing with the truly messy COM implementations. This article also assumes that you know the mechanisms of hosting an ActiveX control and connecting to it for notifications, and although my AX.CPP code includes all functions required, these functions are not discussed in this article in detail.

Also, ActionScript 3.0 knowledge is required.

Creating the ActiveX Control

You may have already been implementing your own methods to insert an ActiveX control in your application, and if so, you do not need to use my AX.CPP to get an IShockwaveFlash pointer. To insert the "Shockwave.Flash" ActiveX control, I use the Win32 ActiveX article discussion and AX.CPP, which merely implements an IOleClientSite and allows me to use the class ID in the resource file:

in order to create an "AX" control (which accepts as the Window title the class ID of the requested ActiveX control). Once we have a HWND, I can send it an AX_QUERYINTERFACE to get a pointer to an IShockwaveFlash:

Loading the SWF

Sending Data to the SWF

Registering the ActionScript Function

Many methods are suggested, and I will use the simplest and the most efficient: The way to call an ActionScript 3.0 function from your C++ code. First, let's define (in frame 1) an ActionScript function in the .FLA file:

import flash.external.ExternalInterface;
// The following is called from our host
function TestFunction1(he:String)
{
this.gotoAndPlay(2);
}
// Register TestFunction1 to be called
flash.external.ExternalInterface.addCallback("foo1",TestFunction1);

What do we have here? Simply a function called "TestFunction1" which accepts a String parameter (This function merely goes to frame 2, leaving the passed string unused, but it is passed so you understand how you would pass arguments to the function).

After that, we must call flash.external.ExternalInterface.addCallback and register the "TestFunction1" as a function that may be called by our container. This function will be visible with the "foo1" name. You can think of a similar thing in DEF file "EXPORTS" section.

Calling the Function

IShockwaveFlash* has a CallFunction member which we can call. It's simple: Flash expects the entity of the call to be passed as a XML Element with the "name" "foo1" and the arguments in XML format. You can learn more on the XML format that Flash expects in this Adobe Help link.

The WM_COMMAND handler in my code demonstrates all this, and the call is shown below:

Getting Notified of Events

OK, we have called an AS 3.0 function, but how could an AS 3.0 function call us? Simply - yes you have guessed it already - via IDispatch.

First, we use standard ActiveX advise mechanism to register for a notification - see AX.CPP and the call to AXConnectObject (you might use your own MFC/ATL methods to connect as well). We pass to it our own IDispatch implementation which, apart from the usual IUnknown and IDispatch methods, implements IDispatch::Invoke as follows:

Let's explain this. We check the dispid for 0xC5, the "FlashCall" function. This function is called from ActionScript through our IDispatch, passing a BSTR with the calling parameters. This as you might have already guessed has the same XML format we used earlier and in my code. I simply display the result in a MessageBox - of course, you want to use my XML library to parse it and handle the function call.

This is the listener for the second button we have created. In this case, the "ext2" will be passed as the "name" variable in the <invoke> element, and the number '2' will be passed as a <number> element in <arguments>.

x64 Compatibility

If you have Flash x64 ActiveX installed (for Internet Explorer), this will also work. Flash support in x64 is really new and for complex AS functions you may run into problems, but eventually everything will work.

The Code

Somewhat dirty (as in all my CodeProject articles ;) but it works. The zip contains:

Project files SLN and VCPROJ for Visual Studio 2008 or later

1.FLA and 1.SWF flash source and movie

AX.H / AX.CPP ActiveX Win32 interfaces

MAIN.CPP which demonstrates all we have said so far.

Other solution files like MAIN.RC, X86.MANIFEST and FUNC.H.

The executable, in case you get bored to open Visual Studio to compile the sample.

I have seen that, in your application if user by default hits enter button from keyboard WM_command message is generated with WPARAM = 1 which is for IDOK button for Win32 dialog which we are using to render our activex, to display flash. Is there a way we can avoid the same and let the flash file itself process the enter hit as is done in browser.
I tried using postmessage "BOOL b = PostMessage(hh, WM_NEXTDLGCTL,(WPARAM)&hX , false) ;" but its not working.
Can you help me with the same.

I mean the approach described in the article demands flash player installed on the user's computer. But what if my application is running on the computer with no flash installed? I would like to have the player embedded completely in my application.

For some of them does mean. My software is used on the computers which are not connected to internet. There's a flash object, which is used to visualize the process my program automates. I thought I could use that object to show the actual data from my software in runtime. Now it seems, that I must search for another visualization tool, because of adobe's policy....

Hi Michael Chourdakis
I am a question ask for you. We want to open you sample code 1.fla to see actionscript 3.0 source code ,but we don't open it(I have used Adobe Flash CS4 and macromedia flash 8 to open it). Could you tell me what kind of software to open it. Thanks

Hi Michael
I know have to use Adobe Flash to explort the .fla and I have used Adobe Flash CS4 and macromedia flash 8 to try open .fla, but Adobe Flash display the 1.fla file format don't correct, so I will to ask you. What are you to use kind of software to edit it. Thanks.