as函数调用交互
随着2020年的到来,flash也逐渐不被各大平台所使用,今天就来讲讲swf文件的交互使用方式
这篇文章纯属技术探讨,请勿用于非法用途。转载请说明来处
写在前面
先说说我为什么会写这篇文章吧。
- 对自己来说是一种总结说明文。
- 前几年学习flash的时候,网上也有很多交互文章,大部分呢只有简约的内容,或者源代码只是截取了一部分,没有完整的开源文件以及例子可供学习,导致很多坑需要自己填。我会将本篇文章内的源代码放入github里供大家学习参考。
- 如果对您有帮助,可以收藏一下。之后的文章也会陆续详细的写下去。内容可能写的不好,希望各位看官可以给予您宝贵的意见。
swf文件的编写
swf文件的编写工具
- flex
- Adobe Flash Professional CC (也叫flashcc 15年以后改名为Animate CC 在支持Flash SWF文件的基础上,加入了对HTML5的支持.)
- other
由于这篇文章主要讲的是交互,具体各位看官使用什么软件就看你们的了。软件的下载方式呢,自行百度吧或者我之后再出个下载链接吧
回归正题,如果要进行交互使用swf 以及调用swf的代码,就要先有个swf文件
在AS代码里开通一个外部接口的调用,如思维导图所示
flash里有个类叫做ExternalInterface 就可以让你的swf文件像dll一样进行内部函数的调用
adobe官方也有详细说明和例子
ExternalInterface - AS3
简单的说需要import flash.external.ExternalInterface;
然后再ExternalInterface.addCallback(“test”,this.test);
就完成了
具体代码如下
package
{
import flash.display.MovieClip;
import flash.external.ExternalInterface;
import flash.text.TextField;
public dynamic class Main extends MovieClip
{
public var val1:TextField;
public var val2:TextField;
public var val3:TextField;
public function Main()
{
super();
ExternalInterface.addCallback("test",this.test);
}
public function test(param1:String = "", param2:String = "") : String
{
this.val1.text = String(param1);
this.val2.text = String(param2);
this.val3.text = String(int(param1) + int(param2));
return this.val3.text;
}
}
}
编译好以后就有了一个swf文件啦。
完成编写后就可以进行嵌入交互工作了。
Html嵌入、交互方法
1.使用swfobject.js来交互
特点:灵活多变,也是常用的调用swf方式
开源项目链接:swfobject
使用方法
首先需要建立一个容器来存放flash文件 我在这里命名为flashContent
<div id="flashContent" style="width:50%;height:50%;text-align:center;">
<a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a>
</div>
<script src="js/swfobject.js"></script>
<dir>
<input type="text" id="a" value="1">
+
<input type="text" id="b" value="2">
<input type="button" name="sub" value="=" onclick="add()">
<input type="button" name="sub" value="a=" onclick="ASadd()">
<input type="text" id="result" value="" >
</dir>
//var flashUrl = "first_loading.swf";
var flashUrl = "test.swf";
var so = new SWFObject(flashUrl, "test", "50%", "50%", "15.0.0","#F2cFf2");
//SWFObject参数分别为 flash的地址,flash的id,高度,宽度,版本,背景色
so.addParam("menu", "false");
//菜单 关闭
so.addParam("wmode", "direct");
//专为flashplayer10及以更高版本新增的参数,绕过浏览器进行渲染,相当于在独立的flashplayer中进行渲染。
so.addParam("allowFullScreen", "true");
//开启全屏
so.addParam("allowScriptAccess", "always");
//脚本调用权限 always代表任何flash都被允许调用脚本
so.addParam("allowFullScreenInteractive", "true");
//仅当在响应鼠标事件或键盘事件时,才能调用启动全屏交互模式的 actionscript。
so.addParam("quality", "high");
//画质 高
so.write("flashContent");
//加载swf文件写入到flashContent里
var a ;
var b ;
//JS函数加法
function add(){
a= document.getElementById("a").value
b= document.getElementById("b").value
var result = parseInt(a) + parseInt(b);
document.getElementById("result").value = result;
}
//调用swf里的函数
function ASadd(){
a= document.getElementById("a").value
b= document.getElementById("b").value
var result = thisMovie("test").test(a,b);//so.swfadd(a,b)
document.getElementById("result").value = "AS_result:"+result;
}
//搭建js与flash互通的环境
function thisMovie(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
}
运行效果
在IE上运行的结果
2.单一object嵌入、调用方式
这种方法的名字叫做 Flash satay,最早是2002年由 Drew McLellan 发表在 A List Apart 上,后来又经过了几次完善:
<object id="test" name="test"
type="application/x-shockwave-flash" data="test.swf" width="550" height="400">
<param name="movie" value="test.swf"/>
<param name="quality" value="high"/>
<param name="allowscriptaccess" value="always"/>
<a href="http://www.adobe.com/go/getflash">
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player"/>
</a>
</object>
<form name="form1" onsubmit="return false;">
<input type="text" id="a" value="1" />
<input type="text" id="b" value="2" />
<input type="button" value="Send" onclick="sendToActionScript();" /><br />
<textarea cols="60" rows="20" name="output" readonly="true">Initializing...</textarea>
</form>
var jsReady = false;
function isReady() {
return jsReady;
}
var a;
var b;
function pageInit() {
jsReady = true;
document.forms["form1"].output.value += "\n" + "JavaScript is ready.\n";
}
function sendToActionScript() {
a = document.getElementById("a").value
b = document.getElementById("b").value
document.forms["form1"].output.value += "AS_result: "+a+"+"+b+"="+document.getElementById("flashContent").test(a,b)+"\n";
}
这个也是adobe官方例子中提供的方法
运行结果
3.双object加载、交互
<object id="exercises" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="214" height="144">
<param name="movie" value="test.swf" />
<param name="wmode" value="window" />
<param name="flashvars" value=""/>
<!--[if !IE]><!-->
<object id="exercisesEx" type="application/x-shockwave-flash"
data="test.swf" width="214" height="144">
<param name="flashvars" value=""/>
<!--<![endif]-->
<!--[if !IE]><!-->
<!--<![endif]-->
<a href="http://www.adobe.com/go/getflashplayer">
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
</a>
<!--[if !IE]><!-->
</object>
<!--<![endif]-->
</object>
4.flex提供的标准方法
HTML代码(这些代码都是flex builder自动生成的,用于将flash嵌入到网页里。)
修改后加入调用方式,基本一样。
- as使用ExternalInterface.addCallback注册回调函数
- 在js函数中根据flash在网页中的id获取实例
- 用上面获取到flash实例,调用as的函数
<noscript>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
id="test" width="100%" height="100%"
codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
<param name="movie" value="test.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#869ca7" />
<param name="allowScriptAccess" value="sameDomain" />
<embed src="test.swf" quality="high" bgcolor="#869ca7"
width="100%" height="100%" name="test" align="middle"
play="true"
loop="false"
quality="high"
allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.adobe.com/go/getflashplayer">
</embed>
</object>
</noscript>
<form name="form1" onsubmit="return false;">
<input type="text" id="a" value="1" />
<input type="text" id="b" value="2" />
<input type="button" value="Send" onclick="sendToActionScript()" /><br />
<textarea cols="60" rows="20" name="output" readonly="true">Initializing...</textarea>
</form>
var a ;
var b ;
function sendToActionScript() {
a = document.getElementById("a").value
b = document.getElementById("b").value
//根据id获取flash实例,在这里id是test,可以从Embed
var flash = (navigator.appName.indexOf ("Microsoft") !=-1)?window["test"]:document["test"];
//调用ActionScript注册的回调方法
document.forms["form1"].output.value +="\n"+ "AS_result: "+a+"+"+b+"="+flash.test(a,b);
}
<!--
// -----------------------------------------------------------------------------
// Globals
// Major version of Flash required
var requiredMajorVersion = 9;
// Minor version of Flash required
var requiredMinorVersion = 0;
// Minor version of Flash required
var requiredRevision = 60;
// -----------------------------------------------------------------------------
// -->
<!--
// Version check for the Flash Player that has the ability to start Player Product Install (6.0r65)
var hasProductInstall = DetectFlashVer(6, 0, 65);
// Version check based upon the values defined in globals
var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
if ( hasProductInstall && !hasRequestedVersion ) {
// DO NOT MODIFY THE FOLLOWING FOUR LINES
// Location visited after installation is complete if installation is required
var MMPlayerType = (isIE == true) ? "ActiveX" : "PlugIn";
var MMredirectURL = window.location;
document.title = document.title.slice(0, 47) + " - Flash Player Installation";
var MMdoctitle = document.title;
AC_FL_RunContent(
"src", "playerProductInstall",
"FlashVars", "MMredirectURL="+MMredirectURL+'&MMplayerType='+MMPlayerType+'&MMdoctitle='+MMdoctitle+"",
"width", "100%",
"height", "100%",
"align", "middle",
"id", "test",
"quality", "high",
"bgcolor", "#869ca7",
"name", "test",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);
} else if (hasRequestedVersion) {
// if we've detected an acceptable version
// embed the Flash Content SWF when all tests are passed
AC_FL_RunContent(
"src", "test",
"width", "100%",
"height", "100%",
"align", "middle",
"id", "test",
"quality", "high",
"bgcolor", "#869ca7",
"name", "test",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);
} else { // flash is too old or we can't detect the plugin
var alternateContent = 'Alternate HTML content should be placed here. '
+ 'This content requires the Adobe Flash Player. '
+ '<a href=http://www.adobe.com/go/getflash/>Get Flash</a>';
document.write(alternateContent); // insert non-flash content
}
运行结果
C++嵌入、交互方法
在官方给出的使用 ExternalInterface 类
其中外部 API 的 XML 格式
- ActionScript 与承载 Shockwave Flash ActiveX 控件的应用程序间的通信使用特定的 XML 格式对函数调用和值进行编码。
外部 API 使用的 XML 格式分为两种。 -
- 一种格式用于表示函数调用。
-
- 另一种格式用于表示各个值;
- 此格式用于函数中的参数及函数返回值。函数调用的 XML 格式用于对 ActionScript 的调用和来自 ActionScript 的调用。对于来自 ActionScript 的函数调用,Flash Player 将 XML 传递给容器;而对于来自容器的调用,Flash Player 需要容器应用程序将向其传递一个此格式的 XML 字符串。下面的 XML 片断说明了一个 XML 格式的函数调用示例:
<invoke name="functionName" returntype="xml">
<arguments>
... (individual argument values)
</arguments>
</invoke>
节点名 | 属性 | 说明 |
---|---|---|
invoke | name | 指示要调用的函数的名称 |
invoke | returntype | 总是为 xml |
arguments | 无 | 该节点的子节点是使用单个值格式 |
arguments 子节点,格式设置的参数值。每个值(包括函数参数和函数返回值)均使用一个格式设置方案,除了实际值之外,该方案还包括数据类型信息。
ActionScript 类/值 | C# 类/值 | 格式 | 注释 |
---|---|---|---|
null | null | <null/> | |
Boolean true | bool true | <true/> | |
Boolean false | false | <false/> | |
String | string | <string>字符串值</string> | |
Number、int、uint | single、double、int、uint | <number>27.5</number> <number>-12</number> | |
Array(元素可以是混合类型) | 允许混合类型元素的集合,如 ArrayList 或 object[] | ![]() | property 节点定义各个元素,而 id 属性为从零开始的数值索引。 |
Object | 含有字符串键和对象值的字典,如具有字符串键的 HashTable | ![]() | property 节点定义各个属性,而 id 属性为属性名称(字符串)。 |
其他内置或自定义的类 | – | <null/> or <object></object> | ActionScript 将其他对象编码为 null 或空对象。不管是哪种情况,所有属性值都会丢失。 |
重点来了!!敲黑板~
外部 API 可用来与支持 ActiveX 控件的任何编程语言或运行时进行通信,而不仅限于 C# 应用程序。
我们可以使用 F_IN_BOX
F-IN-BOX is a developer’s library to enhance Adobe Flash Player
ActiveX features. It does not use its own engine to display movies but
provide a wrapper around official swflash.ocx/flash.ocx code instead.
Thus it is possible to avoid certain Adobe Flash Player ActiveX
limitations.Both 32-bit and 64-bit versions of Flash ActiveX are supported.
There are Delphi Edition (for Delphi, Builder C++, RAD Studio), .Net
Edition (for C#, VB.Net and other .Net languages) and DLL Edition (for
C++, VB6 and other languages that support dll).
译文
什么是F-IN-BOX?
F-IN-BOX是开发人员的库,用于增强Adobe Flash Player ActiveX功能。
它不使用自己的引擎来显示电影,而是提供围绕官方swflash.ocx / flash.ocx代码的包装。 因此可以避免某些Adobe
Flash Player ActiveX限制。
支持Flash ActiveX的32位和64位版本。
有Delphi Edition(用于Delphi,Builder C ++,RAD Studio)、. Net
Edition(用于C#,VB.Net和其他.Net语言)和DLL Edition(用于C ++,VB6和其他支持dll的语言)。
这是一款商业组件,网上也有很多破解版不过都是付费下载,我这有一个F-IN-BOX 4.5版,将会放在我的github里
// FInBox.cpp
// 本示例修改涉及 FInBox.h FInBox.cpp
#include "stdafx.h"
#include "FInBox.h"
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
//=================================================
//=================MY-ADD-BEG======================
HFPC g_hFPC = NULL;
HWND swfWnd = NULL;
//=================MY-ADD-END======================
//=================================================
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;
// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_FINBOX, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_FINBOX));
// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
// 注释:
//
// 仅当希望
// 此代码与添加到 Windows 95 中的“RegisterClassEx”
// 函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
// 这样应用程序就可以获得关联的
// “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FINBOX));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+2);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_FINBOX);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 400, 300, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
//=================================================
//=================MY-ADD-BEG======================
g_hFPC = FPC_LoadRegisteredOCX();
if (NULL == g_hFPC)
{
::MessageBox(NULL, _T("flash OCX have existed"), 0, 0);
return 0;
}
else
{
//::MessageBox(NULL, _T("flash OCX no existed"), 0, 0);
}
//
RECT rc = {0, 0, 200, 200};
swfWnd = CreateWindow((LPCTSTR)FPC_GetClassAtom(g_hFPC), NULL,
WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
hWnd, NULL, NULL, NULL);
if (NULL == swfWnd)
{
return FALSE;
}
//
SFPCPutMovie FPCPutMovie;
SFPCPutStandardMenu FPCPutStandardMenu;
char exePath[MAX_PATH];
GetCurrentDirectory(MAX_PATH, exePath);
std::string absSwfPath(exePath);
absSwfPath += "/movie.swf";
FPCPutMovie.lpszBuffer = absSwfPath.c_str();//TEXT("D:\\movie.swf");
::SendMessage(swfWnd, FPCM_PUT_MOVIE, 0, (LPARAM)&FPCPutMovie);
FPC_Play(swfWnd);
FPCPutStandardMenu.StandardMenu = TRUE;
::SendMessage(swfWnd, FPCM_PUT_STANDARD_MENU, 0, (LPARAM)&FPCPutStandardMenu);
//=================MY-ADD-END======================
//=================================================
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
python嵌入、交互方法
wxPython是一套基于Python的第三方GUI插件,可用Python制作丰富的图形化界面程序。
安装:pip install wxPython
网站下载安装 https://pypi.org/project/wxPython/#files
demo和docs下载:https://extras.wxpython.org/wxPython4/extras/
# -*- coding: utf-8 -*-
import wx
import os
from xml.dom import minidom
from wx.lib.flashwin import FlashWindow
class EIDataSerializer:
__xmlData=None
def __packNumber(self,p,x):
p.appendChild(self.__xmlData.createElement('number')).appendChild(self.__xmlData.createTextNode(str(x)))
return
def __packString(self,p,x):
p.appendChild(self.__xmlData.createElement('string')).appendChild(self.__xmlData.createTextNode(x))
return
def __packNone(self,p):
p.appendChild(self.__xmlData.createElement('null'))
return
def __packBool(self,p,x):
if x:
p.appendChild(self.__xmlData.createElement('true'))
else:
p.appendChild(self.__xmlData.createElement('false'))
return
def __packDict(self,p,x):
p=p.appendChild(self.__xmlData.createElement('object'))
for k,v in x.items():
n=p.appendChild(self.__xmlData.createElement('property'))
n.setAttribute('id',str(k))
self.__packData(n,v)
return
def __packList(self,p,x):
p=p.appendChild(self.__xmlData.createElement('array'))
i=0
for v in x:
n=p.appendChild(self.__xmlData.createElement('property'))
n.setAttribute('id',str(i))
self.__packData(n,v)
i+=1
return
def __packData(self,p,x): ##将Python的类型打包成XML
t=type(x)
if t in (int,long,float):
self.__packNumber(p,x)
elif t in (str,unicode):
self.__packString(p,x)
elif x==None:
self.__packNone(p)
elif t==bool:
self.__packBool(p,x)
elif t in (list,tuple):
self.__packList(p,x)
elif t==dict:
self.__packDict(p,x)
return
def __unpackNumber(self,p):
try:
return int(p.firstChild.nodeValue)
except ValueError:
try:
return float(p.firstChild.nodeValue)
except ValueError:
return None
def __unpackString(self,p):
return p.firstChild.nodeValue
def __unpackTrue(self):
return True
def __unpackFalse(self):
return False
def __unpackNull(self):
return None
def __unpackUndefined(self):
return None
def __unpackObject(self,p):
d={}
for n in p.childNodes:
d[n.getAttribute('id')]=self.__unpackData(n.firstChild)
return d
def __unpackArray(self,p):
a=[]
for n in p.childNodes:
a.append(self.__unpackData(n.firstChild))
return a
def __unpackData(self,p): ##将Flash传过来的XML解析成Python类型数值
t=p.nodeName
if t=='number':
return self.__unpackNumber(p)
elif t=='string':
return self.__unpackString(p)
elif t=='true':
return self.__unpackTrue()
elif t=='false':
return self.__unpackFalse()
elif t=='null':
return self.__unpackNull()
elif t=='undefined':
return self.__unpackUndefined()
elif t=='object':
return self.__unpackObject(p)
elif t=='array':
return self.__unpackArray(p)
def serializeReturn(self,v):
self.__xmlData=minidom.Document()
p=self.__xmlData
self.__packData(p,v)
return self.__xmlData.toxml()
def serializeCall(self,name,args):
self.__xmlData=minidom.Document()
p=self.__xmlData.appendChild(self.__xmlData.createElement('invoke'))
p.setAttribute('name',name)
p.setAttribute('returntype','xml')
p=p.appendChild(self.__xmlData.createElement('arguments'))
for v in args:
self.__packData(p,v)
s=self.__xmlData.documentElement.toxml()
return s
def deserializeReturn(self,s):
self.__xmlData=minidom.parseString(s)
p=self.__xmlData.documentElement
return self.__unpackData(p)
def deserializeCall(self,s):
self.__xmlData=minidom.parseString(s)
p=self.__xmlData.documentElement#invoke
name=p.getAttribute('name')
args=[]
p=p.firstChild#arguments
for n in p.childNodes:
args.append(self.__unpackData(n))
return (name,args)
class FlashFrame(wx.Frame):
def __init__(self, parent, fid, title):
wx.Frame.__init__(self, parent, fid, title)
sort = -1
self.rootPanel = wx.Panel(self, sort)
self.flashWin = FlashWindow(self.rootPanel)
self.txtBox = wx.TextCtrl(self.rootPanel, wx.NewId())
self.btSend = wx.Button(self.rootPanel, wx.NewId(), "Call Flash")
self.flashSizer = wx.BoxSizer(wx.VERTICAL)
self.flashSizer.Add(self.flashWin, proportion=1, flag=wx.EXPAND)
self.flashSizer.Add(self.txtBox, proportion=0.3, flag=wx.EXPAND|wx.ALL, border=2)
self.flashSizer.Add(self.btSend, proportion=0.3, flag=wx.EXPAND|wx.ALL, border=2)
self.rootPanel.SetSizer(self.flashSizer)
self.rootPanel.SetAutoLayout(True)
self.flashWin.AddEventSink(self)
self.rootPanel.Bind(wx.EVT_BUTTON, self.sendToFlashHandler, self.btSend)
self.flashWin.LoadMovie(0, os.getcwd() + os.path.sep + 'test.swf')
return
def FlashCall(self, xmlStr):
serializer = EIDataSerializer()
xmlStr = xmlStr.encode('utf-8') ##从Flash控件消息接收的XML字符串
print "FlashCall: \n" + xmlStr
name, args = serializer.deserializeCall(xmlStr) ##解析成Python函数名和参数
print name
print args
print args[0]
result = "Python返回: " + args[0]
result = serializer.serializeReturn(result) ##返回值打包成XML
self.flashWin.ctrl.SetReturnValue(result)
def sendToFlashHandler(self, btEvent):
sendStr = self.txtBox.GetValue()
flashFunctionName = "helloFlash"
xmlStr = "<invoke name=\"" + flashFunctionName + "\" returntype=\"xml\">"
xmlStr += "<arguments>"
xmlStr += "<string>" + sendStr + "</string>"
xmlStr += "</arguments>"
xmlStr += "</invoke>"
rValue = self.flashWin.ctrl.CallFunction(xmlStr)
print "Flash返回: ", rValue
app = wx.PySimpleApp()
frame = FlashFrame(None, -1, "Python & Flash")
frame.Show(True)
app.MainLoop()