JavaScript桌面程序开发框架介绍

在传统观念中,JavaScript 被认为是一种仅限于浏览器中运行的脚本语言。然而,随着技术的发展,JavaScript 的应用范围已经远远超出了网页。现在,即使在桌面应用程序的开发中,JavaScript 也扮演着越来越重要的角色。本文将介绍一个框架,它允许开发者使用 JavaScript 来构建传统的桌面程序,而无需了解 C 或 C++ 等语言。

通常,要在桌面计算机上运行自己编写的程序,需要学习如 C、C#、Pascal 等编程语言。这些语言可以将代码编译成可执行文件。然而,JavaScript由于其运行在浏览器上的特性,并不能直接用于创建桌面应用程序。传统上,使用 C/C++ 来完成这项工作,尽管它们有明显的缺点,比如需要安装庞大的开发工具(如 Visual Studio),编写代码、编译、链接等一系列步骤才能得到可执行程序。一旦程序被分发给客户端,程序的逻辑通常是固定的,这意味着很难改变其行为。

使用如 JavaScript、Lua、Python 等脚本语言是解决上述问题的常见方法。但在大多数情况下,脚本语言通常作为扩展其能力的辅助工具。本文将介绍一个框架,它允许完全使用 JavaScript 来完成桌面程序的开发。

项目介绍

众所周知,QuickJS 是一个高性能的JavaScript运行时环境。SOUI 是一个高性能的直接 UI 库,两者都是用 C++ 构建的。如果能够将 SOUI 的接口导出到 JavaScript,将得到一个新的框架,开发者可以在 XML 中设计 UI,并使用 JavaScript 编写逻辑。这项工作现在由模块 soui4js 完成。

在解释代码如何工作之前,让先看一下项目的文件结构。项目包括核心模块 soui4js 和依赖模块 qjsbind。其他文件夹如 extctrl、jsvodplayer、sliveplayer 是播放器演示的服务器。depends 包含 4 个子文件夹,包括 quickjs、soui4、sdl2 和 vodplayer。quickjs 和 soui4 是两个核心模块,sdl2 和 vodplayer 是播放器演示的服务器。

快速开始

在运行演示之前,首先运行 copy_bin.bat。它将把依赖的 DLL 复制到 debug 和 release 文件夹中。然后打开 soui4js.sln 并构建所有内容。确保所有模块都构建成功。现在,将在 debug 或 release 文件夹中找到 xliveplayer.exe,具体取决于选择的配置。

运行 xliveplayer.exe,应该看到类似于以下快照的 UI:

可能会问:“提供的代码都是用 C++ 编写的,JavaScript在哪里?”别急,请给更多的耐心。

在 debug/release 文件夹中,可能会看到很多文件。实际上,它们大多数是直播播放器演示的服务器。构建桌面程序所需的模块是 quickjs、soui4 DLL 和 soui4js.dll。xliveplayer.exe 模块是运行 JavaScript 程序的宿主程序。xliveplayer.exe 使用的代码是固定的,在大多数情况下不应该被更改。

需要编写的所有工作是编写一个 main.js 并提供一个 main 函数。运行 xliveplayer.exe 将自动加载 main.js 并运行 main 函数。由于 xliveplayer.exe 实现了相对固定的逻辑,为了避免重建类似的 js 主机,可以简单地将其名称更改为想要的任何名称。

main.js 结构

演示中包含的 main.js 相对复杂。为了简单起见,这里使用了另一个项目来解释。

下载源代码,zip 文件包含一个 main.js 和一个 uires.zip。将其解压缩到一个文件夹中(例如,d:\md5calc),并使用命令 xliveplayer.exe d:\md5calc 来加载 md5calc。如果运行成功,可以将文件拖到 UI 上,将看到以下 UI。

这个程序相当简单:它加载 uires.zip 作为资源。它创建了一个包含 listview 控件的主窗口并显示该窗口。它进入一个消息循环并等待用户输入。

代码示例

以下是 main.js 的代码示例:

import * as soui4 from "soui4"; import * as os from "os"; import * as std from "std"; var g_workDir = ""; class MainDialog extends soui4.JsHostWnd { constructor() { super("layout:dlg_main"); this.onEvt = this.onEvent; } // ... }; function main(inst, workDir, args) { soui4.log(workDir); g_workDir = workDir; let theApp = soui4.GetApp(); let souiFac = soui4.CreateSouiFactory(); // 展示如何从 zip 文件加载资源 let resProvider = soui4.CreateZipResProvider(theApp, workDir + "\\uires.zip", "souizip"); if (resProvider == 0) { soui4.log("load res from uires.zip failed"); return -1; } let resMgr = theApp.GetResProviderMgr(); resMgr.AddResProvider(resProvider, "uidef:xml_init"); resProvider.Release(); let hwnd = soui4.GetActiveWindow(); let hostWnd = new MainDialog(); hostWnd.Create(hwnd, 0, 0, 0, 0); hostWnd.SendMessage(0x110, 0, 0); // 发送初始化对话框消息 hostWnd.ShowWindow(1); // 1==SW_SHOWNORMAL souiFac.Release(); let ret = theApp.Run(hostWnd.GetHwnd()); hostWnd = null; soui4.log("js quit"); return ret; } globalThis.main = main; import * as soui4 from "soui4";

最重要的是,使用代码 import soui4 APIs,可以使用它来显示 UI 并实现逻辑和一切。

待办事项

目前调试程序相对困难。必须查看日志以确保代码是否按预期运行。有一个演示如何调试 quickjs 的仓库在 https://github.com/koush/vscode-quickjs-debug,如果时间允许,希望能够将其整合到这项工作中。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485