posts - 496,comments - 227,trackbacks - 0

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
  • flex
    • com/darronschall/controls/
    • 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, then look in 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 阅读(397) 评论(0)  编辑  收藏 所属分类: flash