INCLUDE_DATA

Passing XML data to ExternalInterface

From version 3.0 ActionScript does not allow pass values directly from/to container by using SetVariable/GetVariable. This method has been replaced by ExternalInterface class.

ExternalInterface API allows comunicate between Flex and parent container. The container can by any browser with full JavaScript language support or external application with embeded Flash ActiveX component (Shockwave Flesh – like Flesh9d.ocx).

First we will start to send normal string value to Flex program.
Here is description how it can be done.

1. In your flex program create a function which you would like to expose to external container

private function XMLReceiver(s:String):Boolean {
    trace("XMLReceiver called with parameter " + s)
    return true;
}

2. Register function to make your function exposed to external container.

import flash.external.ExternalInterface;

private function InitializeForm():void
{
  ExternalInterface.addCallback("FlexXMLReceiver",XMLReceiver);
}

Your function XMLReceiver will be exposed as a function with name FlexXMLReceiver

InitializeForm function you can call automaticaly by execute it on creationComplete action like in example below.

...creationComplete="InitializeForm()" ..

3. Before you call Flex function from container you must load flex program into container.
Hereby an example written in Visual Basic

Private Sub Form_Load()
    ShockwaveFlash1.LoadMovie 0, "thisFlexApp.swf"
End Sub

4. Create SendXMLDataToFlex procedure in your flex container

Private Procedure SendXMLDataToFlex()
  Dim sCall As String

  Const myFuncName = "FlexXMLReceiver"

  sCall = "foobar>"

  Debug.Print ShockwaveFlash1.CallFunction(sCall)
End Function

When you execute this procedure you will pass foobar value to function XMLReceiver exposed as function with name FlexXMLReceiver.

Lets complicate a bit our scenario and try to pass an XML value.
Unfortunatelly you cannot pass directy an XML value… when you do this only first element will be passed to function.
Where are the rest… It looks that internal ActionScript parser get rid of this.

One of the workaround is convert every character of XML value to Hexadecimal representation and then pass this value to flex.
You can do this by implemeting function like below

Private Function ConvertToHexString(ByVal msg As String) As String
    Dim i As Long

    For i = 1 To Len(msg)
        ConvertToHexString = ConvertToHexString & CStr(Hex(Asc(Mid(msg, i, 1))))
    Next i
End Function

All you need is add conversion function call to your procedure SendXMLDataToFlex like below

Private Procedure SendXMLDataToFlex(byVal thisXML as string)
  Dim sCall As String

  Const myFuncName = "FlexXMLReceiver"

  sCall = "" & ConvertToHexString (thisXML)  & ">"

  Debug.Print ShockwaveFlash1.CallFunction(sCall)
End Function

In your flex function you will receive encoded hex string. All you need is convert from hex represenation back to normal xml string.
You can do this by adding ActionScript function ConvertFromHexString

private function ConvertFromHexString(s:String):String {

             var thisHexChar:String;
	var retString:String = "";

	 for (var i:int =0; i < s.length/2; i++) {

	        	thisHexChar	= s.charAt(i*2).toString() + s.charAt((i*2)+1).toString();
		thisHexChar = "0x" + thisHexChar;
		retString = retString + String.fromCharCode(int(thisHexChar));
	   }
  	return retString;
	}

and slightly modify your orginal XMLReceiver function

private function XMLReceiver(s:String):Boolean {
   var xmlString:String;
    xmlString = ConvertFromHexString(s);
    trace("XMLReceiver called with parameter " + xmlString )
    return true;
}

You can do whatever you want with passed XML value like populating data grid.