《Swf文件的那些事》—as函数跨平台的交互详解

1 篇文章 0 订阅
1 篇文章 1 订阅

as函数调用交互

随着2020年的到来,flash也逐渐不被各大平台所使用,今天就来讲讲swf文件的交互使用方式

这篇文章纯属技术探讨,请勿用于非法用途。转载请说明来处

写在前面

先说说我为什么会写这篇文章吧。

  • 对自己来说是一种总结说明文。
  • 前几年学习flash的时候,网上也有很多交互文章,大部分呢只有简约的内容,或者源代码只是截取了一部分,没有完整的开源文件以及例子可供学习,导致很多坑需要自己填。我会将本篇文章内的源代码放入github里供大家学习参考。
  • 如果对您有帮助,可以收藏一下。之后的文章也会陆续详细的写下去。内容可能写的不好,希望各位看官可以给予您宝贵的意见。
    swf交互的思维导图

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文件啦。
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浏览器运行效果
在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官方例子中提供的方法

运行结果
IE运行结果

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
}

运行结果
IE运行结果图:Flex

C++嵌入、交互方法

在官方给出的使用 ExternalInterface 类
其中外部 API 的 XML 格式

  • ActionScript 与承载 Shockwave Flash ActiveX 控件的应用程序间的通信使用特定的 XML 格式对函数调用和值进行编码。
    外部 API 使用的 XML 格式分为两种。
    1. 一种格式用于表示函数调用。
    1. 另一种格式用于表示各个值;
  • 此格式用于函数中的参数及函数返回值。函数调用的 XML 格式用于对 ActionScript 的调用和来自 ActionScript 的调用。对于来自 ActionScript 的函数调用,Flash Player 将 XML 传递给容器;而对于来自容器的调用,Flash Player 需要容器应用程序将向其传递一个此格式的 XML 字符串。下面的 XML 片断说明了一个 XML 格式的函数调用示例:
<invoke name="functionName" returntype="xml"> 
    <arguments> 
        ... (individual argument values) 
    </arguments> 
</invoke>
节点名属性说明
invokename指示要调用的函数的名称
invokereturntype总是为 xml
arguments该节点的子节点是使用单个值格式

arguments 子节点,格式设置的参数值。每个值(包括函数参数和函数返回值)均使用一个格式设置方案,除了实际值之外,该方案还包括数据类型信息。

ActionScript 类/值C# 类/值格式注释
nullnull<null/>
Boolean truebool true<true/>
Boolean falsefalse<false/>
Stringstring<string>字符串值</string>
Number、int、uintsingle、double、int、uint<number>27.5</number> <number>-12</number>
Array(元素可以是混合类型)允许混合类型元素的集合,如 ArrayList 或 object[]Arrayproperty 节点定义各个元素,而 id 属性为从零开始的数值索引。
Object含有字符串键和对象值的字典,如具有字符串键的 HashTableObjectproperty 节点定义各个属性,而 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()
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SWFTools is a collection of utilities for working with Adobe Flash files (SWF files). The tool collection includes programs for reading SWF files, combining them, and creating them from other content (like images, sound files, videos or sourcecode). SWFTools is released under the GPL. The current collection is comprised of the programs detailed below: • PDF2SWF A PDF to SWF Converter. Generates one frame per page. Enables you to have fully formatted text, including tables, formulas, graphics etc. inside your Flash Movie. It's based on the xpdf PDF parser from Derek B. Noonburg. • SWFCombine A multi-function tool for inserting SWFs into Wrapper SWFs, contatenating SWFs, stacking SWFs or for basic parameter manipulation (e.g. changing size). • SWFStrings Scans SWFs for text data. • SWFDump Prints out various informations about SWFs, like contained images/fonts/sounds, disassembly of contained code as well as cross-reference and bounding box data. • JPEG2SWF Takes one or more JPEG pictures and generates a SWF slideshow from them. Supports motion estimation compression (h.263) for better compression of video sequences. • PNG2SWF Like JPEG2SWF, only for PNGs. • GIF2SWF Converts GIFs to SWF. Also able to handle animated gifs. • WAV2SWF Converts WAV audio files to SWFs, using the L.A.M.E. MP3 encoder library. • AVI2SWF Converts AVI animation files to SWF. It supports Flash MX H.263 compression. Some examples can be found at examples.html. (Notice: this tool is not included anymore in the latest version, as ffmpeg or mencoder do a better job nowadays) • Font2SWF Converts font files (TTF, Type1) to SWF. • SWFBBox Allows to read out, optimize and readjust SWF bounding boxes. • SWFC A tool for creating SWF files from simple script files. Includes support for both ActionScript 2.0 as well as ActionScript 3.0. • SWFExtract Allows to extract Movieclips, Sounds, Images etc. from SWF files. • AS3Compile A standalone ActionScript 3.0 compiler. Mostly compatible with Flex. SWFTools

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值