March 13, 2008 6:20 PM
Ely Greenfield's Flex Ajax Bridge is a beautiful piece of work. It
impressed me so much that I translated the javascript part of it to
C++. Just like FABridge for javascript, the Flex C++ bridge
allows you to do most of the things you can do with actionscript via
C++. Of course, the syntax is not as pretty as it would be in
javascript but it does let you develop C++ applications with a Flex
UI.
What?
Nothing explains it like code. Take a look at the following C++ snippet1:
oRootObj.Call("getbutton1").Call("addEventListener", "click", SampleCallback);
void SampleCallback(CASObject& obj, CFlexBridge* pBridge)
{
CASObject oRootObj;
pBridge->Root(oRootObj);
oRootObj.Call("getpanel1").Call("settitle", "Title from CPP");
}
pBridge->ClassRef("mx.controls.Alert").Call("show", "StaticClassCalled");
CASObject oDGrid = pBridge->Create("mx.controls.DataGrid");
oRootObj.Call("addChild", oDGrid);
Flex C++ Bridge is a C++ library that lets you communicate with Flex
in a manner more suited for the normal C++ programmer, i.e, you can
communicate to flex from c++ by writing code like shown above.
Once you put the Flex Ajax bridge into a Flex application, it is
exposed to scripting in the browser. You can use a slightly modified
version of the same FABridge.as2 (or even the same one) on the
actionscript side and the flex application is exposed to the Flex C++
Bridge.
Flex is for the web, AIR is for the desktop. What is this for?
This is for C++ applications that need an awesome UI but do not want
to re-write their existing c++ code and libraries to actionscript /
javascript. It's a normal desktop application, you can interact with
all your favorite C++ libraries and APIs and still have all the rich
expressiveness that flex can deliver.
You could do all this before as well, but the bridge makes it really
easy to use Flex from C++. A lot of the reasons for FABridge
applies to this as well, but this is outside the browser realm so
those reasons have to be filtered to suit that particular fact.
Where can I get it from?
The project is licensed under MPL 1.1 and both the C++ and
actionscript source code is available at code.google.com.
It's open source, so feel free to participate and contribute to it.
Sample Applications
Note: The source (both flex and cpp) is available for all the examples.
AdvancedDataGrid that supports Excel formulae computation:
Here, each individual cells in the ADG are editable. You can type in
any Excel formula into it and hit the "Compute" button. The
application invokes Excel using COM, computes the results and
populates the result into the ADG.
Scan images right into flexbook:
When the Scan button is clicked, a TWAIN dialog pops up letting you
use your scanner to scan images directly into the pages of the
flexbook component.
Sample app showing two flash player instances each with a flex application:
The bridge supports multiple flash player instances. It can talk to
each instance in a different manner. If you look at the screenshot,
both the instances are loading the same swf file. But the C++ code for
one instance adds a datagrid and removes an element shown in the pie
chart.
How does it work?
The flash player ActiveX control is added to a MFC dialog. Now
the content in the flash player can talk to the C++ application via
ExternalInterface. ExternalInterface.call("fnname") will
dispatch a FlashCall message on the C++ side which will have the
arguments passed to call() in XML. This XML has to be parsed to
understand what the message was from the actionscript side.
All this complexity is hidden by the bridge. The bridge talks with the
actionscript side of Ely's FABridge and facilitates calling and
referencing to actionscript objects, classes and methods.
There are multiple worker threads waiting to process incoming or
outgoing flash requests so that the main MFC thread does not
block. The bridge can even support multiple flash player instances
each with it's own bridge back to the C++ application.
Also, Actionscript exceptions are serialized and thrown on the C++
side.
C++ Syntax Rules
To start off, you need the root object which is the main application
object of your flex application. Now you can access the public methods
and properties of your application.
Getters and setters are treated differently: A property "width" will
be translated to "getwidth" for retrieving the value and "setwidth"
for setting the value. Ely's FABridge had camel casing here, but
that has been removed so that constants like MOUSE_DOWN don't confuse
the bridge.
The "Call" method shown in the snippets above take a string as the
first argument that is the name of the method or property (suitably
modified using above defined rules) and the arguments for it. Common
types like string, int, reference to an AS object, custom anonymous AS
object etc are converted internally to an ASObject thanks to copy
constructors and operator overloads.
For more examples of the syntax, take a look at the Worker() method in
ASWorkSample.cpp.
FABridge did not originally have support for accessing methods
and variables of static classes. This was added by Devin Garner and I
have incorporated his code into FABridge.as along with some of my
changes.
Fine Print
Currently, it supports only Windows since it embeds the internet
explorer flash ActiveX control in a MFC dialog.
But it's an open source project and I hope I'll get contributors to
help me make it more platform agnostic.
I'd love to know what you guys think about this and how it's being
used.
CategoryFlexCPPBridge
Comment(s)
[1] Now, this is a better way to communicate rather than saying
m_Shockwave.CallFunction("asfnname") where asfnname has to be exposed
by using ExternalInterface.addCallback on the actionscript side.
[2] Minor changes to support passing of primitives from me and
additional support for accessing static classes, variables and methods
thanks to Devin Garner)