If you've ever tried to load a FlashPaper document in Flex 2, then
you know it's not as straightforward as it was with Flex
1.5.
Sure, you can just use an <mx:SWFLoader /> tag. But, if you've
tried this, you know it's pretty limited. You can't talk to the
FlashPaper document, and the loaded document gets stuck at a fixed size
or scales incorrectly when resized. If you try fiddling with the various
scaleContent and maintainAspectRatio settings, you'll quickly get
frustrated trying to achieve the perfect resize behavior.
I've run into this problem in the Flex 2 application I'm currently
building. We're using ColdFusion to generate dynamic reports via the
<cfreport> tag, capturing the report output as FlashPaper, and
then loading the report output .swf directly into the Flex 2
application. I'm happy to say that I've solved the resize and
communication issues, and I've been given permission to post these on my
weblog from the client that I've written the code for.
You
can download my Flex 2 FlashPaperLoader here. (.zip archive)
- MIT License
There's a lot of interesting things going on the .zip file. In the
archive you'll find the following files:
- flash
- FlashPaperLoader.fla
- FlashPaperLoader_code.as
- flex
- com/darronschall/controls/FlashPaperLoader.as
- FlashPaperLoaderExample.mxml
Note that the code is mostly complete but it is not a compile-ready
working example. You will need a few tweaks get it
working: You'll need to create a new Flex project named
"FlashPaperLoaderExample" out of the code in the flex subdirectory, copy
the flash/FlashPaperLoader.swf file to the Flex project's bin directory
so it lives along side of the Flex 2 output .swf, change the
"flashPaperURL" in the FlashPaperLoaderExample.mxml to point to a valid
FlashPaper document... and then you should be good to go.
The example file contains an indeterminate progress bar that loads a
FlashPaper document full screen. The progress bar goes away when the
FlashPaper is fully loaded. Try resizing your browser window to see how
the loaded FlashPaper document resizes to fill the available space.
The best way to understand what is going on is to just dive in and
take a look at the code. Start in FlashPaperLoaderExample.mxml, then
FlashPaperLoader.as, then look in FlashPaperLoader_code.as. Basically,
the concept is this:
The FlashPaperLoader Flex control is used to load a Flash 8
ActionScript 2 FlashPaperLoader.swf file, generated from the
FlashPaperLoader.fla file. The FlashPaperLoader.swf file is passed the
URL of the FlashPaper document, as well as a unique identifier
(fpProxyId) and the object/embed name of the Flex client (swfDomId) -
"FlashPaperLoaderExample" in this case. The latter two parameters are
necessary for the communication mechanism between Flex and FlashPaper.
The loaded FlashPaperLoader.swf handles loading the FlashPaper document
and fosters communication between Flex 2 and FlashPaper.
Communication is done through ExternalInterface. By leveraging
JavaScript, the ActionScript 3 code running inside of AVM2 can
communicate with the ActionScript 2 code running inside of AVM1. There
is no way for the two different VMs to talk directly, so JavaScript acts
as the middle man.
So, if the Flex client needs to resize the FlashPaper document, it
calls a JavaScript method such as "APP.setSize82" where "82" is the
fpProxyId unique identifier and "APP" is the object/embed id/name
attribute of the Flex client embedded in the HTML page. The
FlashPaperLoader.swf file registers a handler for the JavaScript method
setSize82 with its own internal setSize method, so when the Flex client
invokes the JavaScript method, the FlashPaperLoader.swf file picks it
up. Then, in turn, the loader .swf just invokes the setSize method on
the loaded FlashPaper document passing in the appropriate width and
height. A similar process is used for going from FlashPaper to Flex 2.
The reason the fpProxyId is needed is for when the Flex client loads
multiple FlashPaper documents. The Flex client needs to know that it's
calling a method on the appropriate FlashPaper target, so the id is used
to differentiate the different loaded loader .swf files.
I know it sounds a little confusing, but everything is explained
inside of the source code.
There are a few improvements that can be made to this code. One of
them is that I'm only exposing the "setSize" and "printTheDocument"
methods from the IFlashPaper
interface. Obviously, there are a lot more methods than that (but that
was all I've needed so far). Additionally, it might be a little cleaner
to use FlashInterface
for the communication between AVM1 and AVM2, but I wrote my code some
two months ago and didn't feel the need to change the basics of it since
it's been working flawlessly for me. Also, you might want to have the
FlashPaperLoader.swf proxy the percentage complete when loading a
FlashPaper document so the Flex 2 client can update the loaded progress
correctly.
I hope that helps! I know a few people have been asking about this,
so hopefully my code will get things working for you as well. As I said,
I've been using this technique for awhile nowâ ¦ Good luck!
posted on 2010-04-03 23:42
SIMONE 阅读(486)
评论(0) 编辑 收藏 所属分类:
flash