一、基本原理及过程
Flash通过ExternalInterface类与容器应用程序进行通信。为此,ExternalInterface类提供两个静态属性和两个静态方法。
ExternalInterface.call(“函数名”,[参数…])方法执行容器应用程序的代码,该方法至少需要一个字符串参数来指定要调用的函数名,其它任何参数将作为参数被传递给被调用函数。在除浏览器外的其它容器中,此方法调用将导致flash player ActiveX控件的flashcall事件发生。Flash Player 将指定的函数名及所有参数序列化为一个 XML 字符串。容器可以在事件对象的 request 属性中访问该信息,并用它来确定如何执行它自己的代码。为了将值返回 ActionScript,容器代码调用 ActiveX 对象的 SetReturnValue() 方法,并将结果(序列化为一个 XML 字符串)作为该方法的参数进行传递。——以上摘自帮助文档
其基本过程为:flash调用—>flash自动将参数打包为xml—>将xml传递给C# —>C#解析参数得到函数名与参数值—>执行C#函数—>将返回值打包为xml—>将xml文件发送回flash—>flash自动解析xml得到返回值
从容器中调用 ActionScript 代码必须执行两项操作:向 ExternalInterface 类注册函数,然后从容器的代码调用它。在运行于台式机应用程序中调用 ActionScript 函数时,必须将已注册的函数名及所有参数序列化为一个 XML 格式的字符串。然后,将该 XML 字符串作为一个参数来调用 ActiveX 控件的 CallFunction() 方法,以实际执行该调用。
其基本过程为:flash中注册函数——将要调用的函数名、参数等信息打包为xml—>将xml传递到flash中执行调用—>执行ActionScript函数—>flash自动将结果打包为xml—>将结果xml传递回C# —>C#解析xml得到返回值
可见,flash与C#通信是通过特定格式的xml文件进行的,因此为了实现通信,C#必须实现一下功能:识别该xml格式以得到flash发送来的信心,将需要传送给flash的信息打包成flash能识别的xml格式。为了使用方便我们可以设计一个代理类专门负责数据的解析与打包工作,这样我们就可以透明的使用该代理类来实现flash与C#间的互相调用。
在flash的示例中有一个IntrovertIM_CSharp项目较好的实现了代理的编写,一般情况下,使用该示例中的ExternalInterfaceProxy类足以满足要求,因此方便起见我也直接采用了该代理类。
该类的使用非常简单,通过将flash控件作为参数传递给该类的构造函数,我们就可以建立一个给控件的代理,简单的响应代理的ExternalInterfaceCall事件及使用代理类的Call()方法就能实现与flash通信,中间的数据转换工作完全由代理透明的实现,用户无需关心。
其它语言及程序课根据上面原理编写自己的代理类来实现数据的解析与打包工作。
二、配置vs
第一步C#添加组件
打开VS2005-工具-选择工具箱项-COM组件-选择Shockwave Flash Object-确定
添加好组件往场景上拖放,如果提示注册需求注册
c# 注册控件-在运行输入-回车(flash9f.ocx这个文件以系统中实际文件为准。)
regsvr32 c:/windows/system32/macromed/flash/flash9f.ocx
或者regsvr32 c:/windows/system32/macromed/flash/flash10a.ocx(最好找到这个目录看下自己的flash的版本,找到ocx后缀的文件。)
第二步将Flash组件拖入场景
将Flash组件拖入场景,设置加载的swf路径。设置组件id。
组件的Movie属性:指定要播放的swf的路径,
如果swf在本地硬盘,则需要写成 从盘符开始的绝对路径
如果swf在某网站上,则需要写成 完全的url网址
更多该组件属性/方法
三、交互代码
C#调用as脚本:
//C# 代码
private void CSharpCallAs_Load(object sender, EventArgs e)//窗体加载时
{
axShockwaveFlash1.Movie = Application.StartupPath + "//example.swf";
axShockwaveFlash1.FlashCall += new AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEventHandler(axShockwaveFlash1_FlashCall);
}
private void axShockwaveFlash1_FlashCall(object sender, AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEvent e)//向as发送请求
{
//没有任何代码也可以;
}
private void button1_Click(object sender, EventArgs e)
{
callFunction("output","why?");//调用as中的output()函数,why?为参数
}
private void callFunction(string funName, string arg)
{
//C#传给Flash的值
axShockwaveFlash1.CallFunction("<invoke name=/"" + funName + "/" returntype=/"xml/"><arguments><string>" + arg + "</string></arguments></invoke>");
}
//as脚本
package{
import flash.display.*;
import flash.text.*;
import flash.external.ExternalInterface;
public class example extends flash.display.MovieClip{
var tf:TextField;
public function example(){
tf=new TextField();
ExternalInterface.addCallback("output",output);//这是外部接口,让C#可以调用
//output("feel");
trace("study!")
}
public function output(str:String):void{
tf.text=str;
tf.textColor=0xff0000;
this.addChild(tf);
}
}
}
就这几句就可实现C#调用as,不是简单的很吗?
as调用C#
//as脚本
package{
import flash.display.*;
import flash.geom.ColorTransform;
import flash.geom.Transform;
import flash.net.SharedObject;
import flash.net.URLRequest;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.external.ExternalInterface;
public class changecolor extends flash.display.MovieClip{
private var rect:Sprite;
private var mySo:SharedObject;
public function changecolor(){
rect=new Sprite();
mySo=SharedObject.getLocal("test1");
var colorHex:String=mySo.data.colorValue;
var flushResult:Object=mySo.flush();
trace("flushResult:"+flushResult);
trace(mySo.data.colorValue);
rect.graphics.beginFill(mySo.data.colorValue);
rect.graphics.drawRect(100,100,200,150);
rect.buttonMode=true;
rect.addEventListener(MouseEvent.CLICK,callCSharp);
rect.graphics.endFill();
this.addChild(rect);
}
public function callCSharp(event:MouseEvent):void
{
var strResult:String=ExternalInterface.call("callCSharp");
trace("test");
}
}
}
//C#代码
private void axShockwaveFlash1_FlashCall(object sender, AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEvent e)
{
XmlDocument document = new XmlDocument();
document.LoadXml(e.request);
// get attributes to see which command flash is trying to call
XmlAttributeCollection attributes = document.FirstChild.Attributes;
// get function
String command = attributes.Item(0).InnerText;
// get parameters
XmlNodeList list = document.GetElementsByTagName("arguments");
switch (command)
{
case "callCSharp":
callCSharp();
break;
}
}
private void Form3_Load(object sender, EventArgs e)
{
axShockwaveFlash1.Movie = Application.StartupPath +"changecolor.swf/";
axShockwaveFlash1.FlashCall+=new AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEventHandler(axShockwaveFlash1_FlashCall);
}
public void callCSharp()
{
ColorDialog colorDialog = new ColorDialog();
colorDialog.ShowDialog();
Color color = colorDialog.Color;
}