65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 XML 和 JavaScript 构建桌面程序,无需 C/C++

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2023 年 2 月 9 日

CPOL

5分钟阅读

viewsIcon

7189

downloadIcon

100

介绍一个使用 XML 和 JS 构建客户端程序的新框架

引言

如果您会使用 JavaScript,那么您无需依赖 Web 浏览器即可构建桌面程序。是的,这是真的。由于我已经将 soui4 的所有必要 API 导出到了 JavaScript,现在 JS 程序员可以开发传统的桌面程序了。与设计网页类似,可以通过准备图像、颜色、字体等资源,并将它们用于编写用户界面的布局到 XML 文件中,然后编写 JS 程序使用此框架控制程序的逻辑来完成桌面程序的开发。在此过程中,您无需了解 C 或 C++ 的任何知识。

背景

通常,要让您的想法在桌面计算机上运行,您需要学习一门编程语言,如 C、C#、Pascal 等。它们可以将您的代码构建成可执行文件。然而,JavaScript 无法完成这项工作,因为它在 Web 浏览器中运行。传统上,尽管 C/C++ 有明显的缺点,我们仍使用它们来完成这项工作。例如,一个人必须安装一个巨大的开发工具,如 Visual Studio,并且需要编写代码、编译它们、链接它们才能得到一个可执行程序,一旦程序分发到客户端,程序的逻辑通常就固定了,这意味着很难改变其行为。

使用脚本语言(如 js、lua、py 等)是处理上述问题的常见方法。然而,在大多数情况下,脚本语言通常是扩展其功能的辅助工具。

在本文中,我想向您介绍一个框架,使用这个框架,您可以使用 JavaScript 完全完成桌面程序的开发。

实际上,我曾经实现过一项类似的工作,只是当时使用的是 Lua 作为脚本语言。在那项工作中,一部分基本 API 被导出到 Lua 环境,这更像是一个演示而不是一个实用的框架(主要原因是Lua我不太熟悉)。请参阅《Run Client in Lua Script completely》

项目介绍

众所周知,quickjs 是一个高性能的 JavaScript 运行时。也许有人知道 SOUI 是一个高性能的 directui 库。它们都是用 C++ 构建的。

如果我们能将 SOUI 的接口导出到 JavaScript,我们就会得到一个新的框架,使用这个框架,你可以用 XML 设计 UI,用 JS 编写逻辑。这项工作现在由 soui4js 模块完成。

在解释代码如何工作之前,让我们先看一下项目的目录结构。

该项目包括核心模块 soui4js 和一个依赖模块 qjsbind。其他文件夹,如 extctrljsvodplayersliveplayer,用于播放器演示。

depends 包含 4 个子文件夹,包括 quickjssoui4sdl2vodplayer

quickjssoui4 是两个核心模块。sdl2vodplayer 用于播放器演示。

在运行演示之前,请先运行 copy_bin.bat。它会将依赖的 DLL 复制到 debugrelease 文件夹。

然后打开 soui4js.sln 并生成所有。确保所有模块都已成功生成。

现在,您将在 debugrelease 文件夹中找到 xliveplayer.exe,具体取决于您选择的配置。

运行 xliveplayer.exe,您应该会看到 UI 如下快照所示

你骗人!你提供的所有代码都是用 C++ 写的。JavaScript 在哪儿?

冷静点!请再给我一些耐心。

您可能会在 debug/release 文件夹中看到不少文件。实际上,其中大部分都用于直播播放器演示。

构建桌面程序所需的模块是 quickjssoui4 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。

这个程序很简单

  1. 它加载 uires.zip 作为资源。
  2. 它创建一个包含 listview 控件的主窗口并显示该窗口。
  3. 它进入消息循环并等待用户输入。

现在,让我们看看代码

import * as soui4 from "soui4";
import * as os from "os";
import * as std from "std";

var <code>g_workDir</code>="";

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();
	// show how to load resource from a zip file
	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);  //send init dialog message.
	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 API,您可以使用它来显示 UI 和实现您的逻辑以及一切。

待办事项列表

  1. 调试程序现在相对困难。我必须查看日志以确保代码按预期运行。有一个仓库演示了如何在 https://github.com/koush/vscode-quickjs-debug 中调试 quickjs。如果有时间,我想将其整合到这项工作中。

关注点

使用这个框架,我们可以在 JavaScript 中完成大部分工作。如果您熟悉 C++,您可以为 js 提供扩展控件,并且可以完成传统程序可以做的任何事情。您认为呢?感谢您的耐心!

历史

  • 2023 年 2 月 9 日:版本 1.0
  • 2023 年 7 月 7 日:版本 1.1
© . All rights reserved.