百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程文章 > 正文

嵌入开源 Flash 控件 Ruffle 桌面版与 Web 版的 2 种方法

qiyuwang 2024-10-12 22:33 15 浏览 0 评论

方法一、使用基于微软 WebView2 的 web.view 嵌入 JS 版 Ruffle

Ruffle 是一个开源免费的 Flash 播放器,网页版 ruffle.js 体积很小,打个包 1.7 MB,调用也非常简单。aardio 标准库中的 web.view ( WebView2 ) 可以完美支持 ruffle.js ,不过我们先要解决 2 个小问题:

1、ruffle.js 通过网址加载 Flash 动画不太正常会报错,但是直接内存加载动画数据没问题。
2、浏览器不能直接用代码访问本地文件。

我们先使用 external 接口导出 aardio 函数来解决上面的问题,使用 aardio 将远程或本地的 swf 文件先读入到内存,再转换为字节数组传给 ruffle.js 就可以了,关键代码如下:

import web.view;
var wb = web.view(winform);

wb.external = {
  getSwf = function(){
    //可返回包含 SWF 文件二进制数据的数组、SAFEARRAY,buffer  
    return com.SafeArrayV( inet.http.get("https://update.aardio.com/v10.files/demo/transparent.swf") );
    
    //本地文件可以直接返回 buffer 
    return string.loadBuffer("\res\tet.swf"); 
  }; 
}

给 ruffle.js 返回数组就行(buffer、数组、COM 数组都行), 要注意 string.load 加载文件返回的是字符串,string.loadBuffer() 返回的是字节数组。

网页里面用下面的 JavaScript 加载 Flash 动画:

const ruffle = window.RufflePlayer.newest();
const player = ruffle.createPlayer();

player.style.width = "100vw";
player.style.height = "100vh";

const container = document.getElementById("container");
container.appendChild(player);

player.load({data: await aardio.getSwf() });

在 JS 里用 aardio.getSwf() 调用 aardio 导出的 wb.external.getSwf() 函数,注意所有本地函数在 WebView2 里都是异步函数,所以用了 await 取返回值( 要在异步函数里才能使用 await )。

ruffle.js 最好是通过 HTTP 服务器加载,这在 aardio 中很容易解决,如果创建了 aardio 工程,只要简单地将所有网页以及 ruffle.js 添加到工程的资源目录内,然后用类似:

wb.go( wsock.tcp.simpleHttpServer.startUrl("/res/swf/index.html") )

打开网页就可以了,aardio 会自动使用 HTTP 协议内存加载这个资源目录下的所有文件(可以发布为独立 EXE 文件)。

写范例的时候为了方便大家复制就可以运行,没有创建工程文件,HTML代码与 aardio 代码混写在一起,所以我写了一个扩展库 web.ruffle 用于获取通过 HTTP 服务器访问 ruffle.js 的地址。

首先在 aardio 中导出 getRuffleScriptSrc 函数:

import web.ruffle;
import web.view;
var wb = web.view(winform);

wb.external = {
  getSwf = function(){  
    return com.SafeArrayV( inet.http.get("https://update.aardio.com/v10.files/demo/transparent.swf") ); 
  };
  getRuffleScriptSrc = function(){  
    return web.ruffle.getUrl("/ruffle/ruffle.js");
  }; 
}

然后在 HTML 代码中添加一个空的 script 元素:

<script id="ruffle"></script> 

然后在 JavaScript 中调用 aardio 函数获取到 ruffle.js 的地址并加载该 JS:

var ruffleScript = document.getElementById("ruffle");
ruffleScript.src = await aardio.getRuffleScriptSrc();

完整范例源码请参考 「 aardio 范例 / Web 界面 / web.view / Flash 」

方法二、嵌入 Ruffle 桌面版:钩住外部进程窗口

aardio 扩展库 process.ruffle —— 可以让 Ruffle 桌面版的窗口嵌入我们的软件界面。这个库之前的实现是把 Ruffle 创建的桌面独立窗口加上 WS_CHILD 样式变为子窗口,再指定父窗口,调整大小后嵌入我们的界面。但是这种方式 —— 有时候会出现一些奇怪的问题( 例如 Flash 动画卡住,鼠标晃一下才会动 )。

在 aardio 里还有一个更好的选择:我们可以用 orphanWindow 功能将独立窗口伪装为子窗口,关键代码只有一句:

this._form.orphanWindow(,this.hwndFlash);

Ruffle 桌面版打开 Flash 会创建一个带标题栏,带边框的独立窗口,如果在打开 Flash 动画以后再去移除窗口边框 —— 那就会看到带边框的窗口在屏幕上一闪而过。下面我们就来解决这个问题。

首先我们用 process.apiHook 替代 process 创建 Ruffle 进程:

this.apiHook = process.apiHook(ruffleExePath,args,{
  suspended = true;//启动后暂停 
});

注意参数里指定了进程启动后暂停,下面安装好 API 钩子以后再恢复运行。

下面先安装钩子拦截创建窗口的 API 函数 CreateWindowExW ,以及设置窗口位置的函数 SetWindowPos 。关键代码如下:

//安装 HOOK
this.hookCreateWindowEx = this.apiHook.install("User32.dll"
  ,"CreateWindowExW","CreateWindowExHook.dll","_CreateWindowExHook@48");
  
this.hookSetWindowPos = this.apiHook.install("User32.dll"
  ,"SetWindowPos","CreateWindowExHook.dll","_hookSetWindowPos@28");

然后再获取外部进程的 hookSet 函数并转换为 aardio 函数调用:

var hookSet = this.process.remoteApi("void(addr pc,addr ps,addr hwndHost)"
  ,"CreateWindowExHook.dll","hookSet","cdecl");
  
hookSet(
  this.hookCreateWindowEx.addrTrampoline,//这是原来的 CreateWindowEx 函数指针地址 
  this.hookSetWindowPos.addrTrampoline,//这是原来的 SetWindowPos 函数指针地址 
  this._form.hwnd
);

现在可以用下面的代码让进程继续运行了:

this.process.resume();

再加上下面的代码保证主进程退出时 ruffle.exe 也会自动退出:

this.process.assignToJobObject(..process.job.limitKill);

DLL 的源代码很少,在 process.ruffle 扩展库目录下可以找到。要注意 Ruffle 创建了多个窗口,设置参数要避免改动不可见的那个窗口。

测试一下:


调用范例:

import win.ui;
/*DSG{{*/
var winform = win.form(text="开源 Flash 控件 Ruffle";right=759;bottom=512)
winform.add(
static={cls="static";text="Static";left=3;top=1;right=758;bottom=443;db=1;dl=1;dr=1;dt=1;z=1}
)
/*}}*/

import process.ruffle;
var ruffle = process.ruffle(winform.static);
winform.show();

//自定义 Flash 参数
ruffle.flashVars = {k="v",k2=123};


//也可以打开本地文件
ruffle.go("https://ruffle.rs/demo/swfs/wasted_sky.swf"); 
win.loopMessage();

请注意 Ruffle 桌面版不支持 Win7。

相关推荐

windows开启telnet服务,检测远程服务端口是否可以连通

本文介绍windwos开启telnet服务,telnet服务一般可以用于检测远程主机的某个端口服务是否可以连通,在日常的工作中,我们经常会遇到在本地的windows检测远程服务端口是否可以连通。win...

仅在Web登录新华三交换机条件下启用设备Telnet登录方式

概述Web登录新华三交换机可以在“网络-服务”页面中启用设备Telnet服务或SSH服务,也可以在“设备-管理员”设置管理员用户的可用服务,然而,在设备Web页面中,无法设置lineVTY用户线【l...

思科交换机,路由器如何关闭telnet 开启ssh服务

SSH为建立在应用层基础上的安全协议。SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。今天我们就来说说思科交换机,路...

智能化弱电行业常用的DOS命令,掌握了你也能成为...

前言在做智能化弱电项目时,前端摄像头设备安装结束后,我们会对网络摄像头进行调试,调试过程中会遇到前端摄像头没有图像或者图像出来了画面卡顿的现象。我们会采用ping命令来测试网络的连通性和网络承载能力。...

「干货」eNSP模拟器之配置Telnet登录

配置说明:配置Telnet,使R2(模拟PC)通过SW1登录到R1进行管理和配置。操作步骤:system-view##进入系统视图[Huawei]sysnameR1##改名为R1[R1]int...

win11开启telnet服务怎么操作 win11打开telent指令是什么

telnet服务是我们在进行远程连接的时候,必须要打开的一项功能。但是有不少用户们不清楚在windows11系统中怎么开启telnet服务。今天小编就使用详细的图文教程,来给大家说明一下打开telen...

华三(H3C)交换机Telnet的远程登陆

一,配置交换机管理IP[SW1]vlan20//创建管理vlan[SW1]interfacevlan20//进入vlan接口[SW1-Vlanif20]ipaddress192.168....

win10 telnet命令怎么查看端口是否打开

可能大家也会遇到这个问题,win10telnet命令查看端口是否打开的步骤是什么?具体方法如下:1、键盘输入快捷键WIN+R,打开运行窗口。2、输入cmd,点击确定按钮。3、弹出cmd命令行窗...

Windows 7如何打开Telnet功能(win7系统打开telnet)

Windows7默认安装后是没有开启telnet客户端功能的,例如,我们在开始菜单中输入cmd,然后使用telnet命令,会弹出下图提示:‘telnet’不是内部或外部命令,也不是可运行程序或批处理文...

为锐捷路由器交换机开启web和telnet,实现轻松管理

笔者上一篇文章写了关于锐捷二层交换机配置教程,那么接下来讲一下锐捷的路由交换设备配置web、telnet技巧。同样,今天的教程也是基于命令行,比较简单,适合新手小白进行学习。准备工作配置前准备:con...

一文学会telnet命令的用途和使用方法

Telnet是一个古老的远程登录协议,可以让本地计算机获得远程计算机的工作能力。它采用了TCP的可靠连接方式,可以连接任何网络互通的远程计算机。不过由于它采用了明文传输方式,存在安全风险,目前已经很少...

Telnet命令是什么?如何使用?(telnet命令在哪里开启)

telnet命令是一个常用的远程登陆工具,使用它,我们可以快捷地登陆远程服务器进行操作。那么如何使用telnet命令呢?首先,我们需要打开telnet功能,任何电脑默认是关闭此功能的,开启方式如下:打...

win11系统如何开启telnet服务(拷贝版本)

  我们要知道,Telnet协议是Internet远程登陆服务的标准协议,可以使用户在本地计算机上完成远程主机的工作,不过对于一些刚接触win11中文版系统的用户来说,可能还不知道telnet服务在哪...

如何开启telnet客户端(如何开启telnet服务)

Telnet协议是TCP/IP协议家族中的一员,是Internet远程登陆服务的标准协议和主要方式,Telnet是常用的远程控制Web服务器的方法。工作中经常用到telnet客户端,但在windows...

Telnet 是什么,如何启用它?(telnet有什么用)

对于Internet等TCP/IP网络,Telnet是一个终端仿真程序。Telnet软件在您的系统上运行并将您的个人计算机链接到网络服务器。它将所有数据转换为纯文本这一事实被认为是易受...

取消回复欢迎 发表评论: