5 Replies Latest reply on Jan 24, 2011 4:14 PM by indulis.svagers

    Loading external SWF fila and accessing variables/functions

    indulis.svagers

      Hello everybody!

      My first post here. Actually I do search google for answers all the time, but now - it's tough one.

       

      public function loadScreen(swf:File):void {
           _content = swf;
           var swfBytes:ByteArray = new ByteArray();
           var file:File = _content;   
      
           var loadStream:FileStream = new FileStream();
                loadStream.open( file, FileMode.READ );
                loadStream.readBytes( swfBytes );
                loadStream.close();
                                                                       
           var loader:Loader = new Loader();
           var loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
                loaderContext.allowLoadBytesCodeExecution = true;
      
                loader.loadBytes( swfBytes, loaderContext);
                loader.contentLoaderInfo.addEventListener(Event.INIT, accessSWF);
                loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
      }
                
      public function errorHandler(e:Event):void {
           trace("PROBLEM LOADING BYTES");
      }
                
      public function accessSWF(e:Event):void {
           var moduleLoader:LoaderInfo = LoaderInfo(e.target);
           moduleLoader.content.addEventListener(Event.INIT, readyHandler);
      }
                
      public function readyHandler(e:Event):void {
           _initOptions = new NativeWindowInitOptions();
           with(_initOptions) {
                resizable = true;
                transparent = false;
           }
           var boundsWin:Rectangle = new Rectangle(100, 100, 423, 430);
                     
           _window = new NativeWindow(_initOptions);
           with(_window) {
                activate();
                bounds = boundsWin;
                stage.scaleMode = "noScale";
           }
      }
      

       

      The problem is that application loads the external swf with loadBytes, but it's not executing the script. Actually, I'm not able to use the loaded swf. I'm not able even to add it to Stage. But message in output still shows, that the swf file is loaded "[SWF] file.swf/[[DYNAMIC]]/1 - 2746 bytes after decompression"

       

      There are many solutions for this problem on the internet, but they're old (written in 2008 most of all) and not working either, because those solutions work only in older AIR versions

       


      Any help?

        • 1. Re: Loading external SWF fila and accessing variables/functions
          indulis.svagers Level 1

          A bit more: .swf file is located ir applicationStorageDirectory

          • 2. Re: Loading external SWF fila and accessing variables/functions
            indulis.svagers Level 1

            Well, I took a bit deeper look into the problem and found out, that

             

            trace("Width " + moduleLoader.width); //     550
            trace("Width " + moduleLoader.content.width); //     0
            trace("Width " + moduleLoader.loader.content.width); //     0
            

             

            So I understand, that the file is loaded properly, only thing that i do not understand what is the right approach to the Loader object of this file, so I would be able to add it to Stage.

             

            It looks for me, tad the right approach is this one:

             

            var loader:Loader = Loader(moduleLoader.loader);
            

             

            And I think, that it is availible and useable only after some event. Then what is the Event?

            • 3. Re: Loading external SWF fila and accessing variables/functions
              indulis.svagers Level 1

              Well I got a bit further:

              public function loadScreen(swf:File):void {
                   var loadStream:FileStream = new FileStream();
                   with(loadStream) {
                        openAsync( swf, FileMode.READ );
                        addEventListener(ProgressEvent.PROGRESS, loadProgress);
                        addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
                        addEventListener(Event.COMPLETE, loadComplete);
                   }
              }
                        
              public function loadProgress(e:ProgressEvent):void {
                   trace("Loading " + e.target.bytesAvailable);
              }
              
              public function errorHandler(e:IOErrorEvent):void {
                   trace("Error ");
              }
              
              public function loadComplete(e:Event):void {
                   var swfBytes:ByteArray = new ByteArray();
                   FileStream(e.target).readBytes( swfBytes );
                   var loaderContext:LoaderContext = new LoaderContext();
                   with(loaderContext) {
                        allowLoadBytesCodeExecution = true;
                   }
                   var loader:Loader = new Loader();
                   with(loader) {
                        loadBytes( swfBytes, loaderContext);
                        contentLoaderInfo.addEventListener(Event.INIT, completedSWF);
                   }
              }
                        
              public function completedSWF(e:Event):void {
                   var moduleLoader:LoaderInfo = LoaderInfo(e.target);
                   moduleLoader.addEventListener(Event.COMPLETE, initiatedFinally);
              }
                        
              public function initiatedFinally(e:Event):void {
                   _initOptions = new NativeWindowInitOptions();
                   with(_initOptions) {
                        resizable = true;
                        transparent = false;
                                  }
                   var boundsWin:Rectangle = new Rectangle(100, 100, 423, 430);
                   _window = new NativeWindow(_initOptions);
                   with(_window) {
                        activate();
                        bounds = boundsWin;
                        stage.scaleMode = "noScale";
                   }
                   var loader:Loader = e.target.loader;
                   loader.addEventListener(Event.ADDED_TO_STAGE, irAdded);
                   _window.stage.addChild(loader);
              }
              
              public function irAdded(e:Event):void {
                   trace(e.target.content.vars); // Object Dictionary
              }
              

              At this point ( function irAdded ) I'm able to retrieve external SWF's variables. But stil, it's not visible on the stage. And yet - there's another problem - rendering the same script , every second time application unloads the external swf movie.

              • 4. Re: Loading external SWF fila and accessing variables/functions
                indulis.svagers Level 1

                Problem SOLVED!

                Actually, at the last point application added the external swf to stage. Problem was, that swf file in applicationStorageDirectory was empty (had no objects on stage). I rendered the fla file again, and changed the swf file in applicationStorageDirectory. Now it's ok and running.

                There are still the UNLOAD problem, but i added event handler for it. If the UNLOAD event fires, application tries again and again till it's loaded

                • 5. Re: Loading external SWF fila and accessing variables/functions
                  indulis.svagers Level 1

                  Actually, there's few more things solved. If any of you are searching in google for answer, how to access parent variables from external SWF, there might be problems, if the stage is not yet ready. In my case, the stage size is equivalent to the loaded SWF bounds, so NativeWindow is activated within the same class, where the external SWF is loaded. Before you can get to the dimensions of SWF file, file has already executed the code. So, you must do the folowwing:

                       - call init function (located in external SWF) from the main application and try to access parent.parent from the function (should be [object Stage])

                       - I had a different case, so i created the EventDispatcher object in my external SWF and added eventListener to it. Then i fired event from main application, so the parent.parent did not return null. Firing looks something like this EventDispatcher(loaderInfo.content.evt).dispatchEvent(new Event("THE_POINT"))