高级用法

IPC 双向通信

火山 → 前端

发送IPC消息 把 payload 推给指定窗口,前端用 jade.on 接收:

Plaintext
Jade.发送IPC消息 (主窗口ID, "state-changed", "{\"count\":42}")
JavaScript
jade.on('state-changed', payload => {
  const data = typeof payload === 'string' ? JSON.parse(payload) : payload;
  console.log(data.count);
});

推送复杂数据时用内置 json_object 构造,避免手拼转义:

Plaintext
变量 消息 <类型 = json_object>
消息.置文本 ("level", "success")
消息.置文本 ("message", "任务完成")
Jade.发送IPC消息 (主窗口ID, "toast", 消息.到文本 ())

前端 → 火山

前端 jade.invoke(通道, payload) 返回 Promise;火山侧回调返回非空文本即应答,空文本不回传:

JavaScript
const res = await jade.invoke('query-user', { id: 1001 }, { timeout: 8000 });
Plaintext
如果 (通道名 == "query-user")
{
    变量 请求 <类型 = json_object>
    请求.创建自文本 (数据)
    变量 应答 <类型 = json_object>
    应答.置整数 ("id", 请求.取整数 ("id", 0))
    应答.置文本 ("name", "张三")
    返回 (应答.到文本 ())
}

前端资源加载三方案

方案调用适用
本地目录置协议服务目录 (取运行目录 () + "web", 热载)开发期 / 资源不敏感
磁盘 JAPK置协议服务目录 ("app.japk", 假)资源打包但随文件分发
内存 JAPK应用包.加载字节集 (...)置协议服务目录 ("")资源加密 + 磁盘零前端文件

三种方式返回的地址都直接传给 创建窗口,与库同源、IPC 无跨域问题。

跨域与 IPC 风险

页面若从外部 http(s):// 域加载,jade.invoke源站白名单JadeViewOptions)约束——不设白名单时外部源无法与宿主通信。协议服务加载的本地页面不受此限制。

JAPK 资源包详解

JAPK 是 JadeView 的前端资源加密 / 签名包格式。内存加载流程:

Plaintext
// 1.(签名包)设置 Ed25519 公钥——设置后只接受签名包
Jade.应用包.设置公钥 ("base64公钥44字符")

// 2. 从字节集加载(也可用 加载视窗文件资源 直接读内嵌资源,实现单 exe 全内置)
变量 结果 <类型 = 整数>
结果 = Jade.应用包.加载字节集 (读入文件 ("app.japk"))
如果 (结果 != 0)
{
    调试输出 ("JAPK 加载失败, 错误码:", 结果)   // 负数错误码,详见 API 参考
}

// 3. 根目录留空 = 服务已加载的内存包,返回 JADE://<应用标识>
变量 地址 <类型 = 文本型>
地址 = Jade.置协议服务目录 ("")

注意事项:

  • JAPK 打包时的应用名 / 应用标识必须与 初始化 传入的一致(错配返回 -6
  • 加载失败详情也会经 应用包加载失败 事件回报
  • 免费版打包的 JAPK 应使用「填路径」方式(置协议服务目录 ("app.japk")),而非字节集内存加载
  • .japk 作为视窗文件资源内嵌后用 加载视窗文件资源,可实现前端资源完全藏进 exe

单实例与协议唤起

初始化 开启单实例后,用户再次启动 exe(含 myapp:// 协议唤起),第二个进程会把完整命令行转发给首实例并退出,首实例收到 第二实例 事件:

Plaintext
// 注册自定义协议(写注册表)
Jade.系统.注册协议 ("myapp")
Plaintext
方法 JadeView_第二实例 <接收事件 类型 = 整数>
参数 来源对象 <类型 = JadeView>
参数 标记值 <类型 = 整数>
参数 窗口ID <类型 = 整数>
参数 数据 <类型 = 文本型>
参数 命令行参数 <类型 = 文本数组类>
{
    如果 (来源对象 == Jade)
    {
        // 唤起主窗口;命令行参数 已自动排除 argv[0] 的 exe 路径
        Jade.窗口.置可视 (主窗口ID, 真)
        Jade.窗口.置焦点 (主窗口ID)
    }
    返回 (0)
}

窗口材质(Windows 11)

Mica / Acrylic 材质由 DWM 在窗口层渲染,前提是:

  1. 窗口选项.透明窗口 = 真
  2. 页面 body 背景透明(CSS background: transparent),否则页面底色盖住材质
  3. 仅 Windows 11 可用——用 Jade.系统.是否为Win11() 判断后降级为 置背景色 纯色底
Plaintext
如果真 (Jade.系统.是否为Win11 ())
{
    Jade.窗口.置材质 (窗口ID, 窗口材质.云母)
}

标题栏方案对比

边框风格标题栏控制按钮拖动
普通窗口系统标题栏系统系统
标题覆盖无标题栏,页面顶到边库内置(右上角,置标题栏覆盖层样式 可调配色)页面标记 jade-region-drag
无标题栏 / 无边框前端自绘(经 IPC 调 最小化 / 最大化切换 / 关闭页面标记 jade-region-drag

页面拖动区用 HTML 布尔属性标记(运行时自动注入,无需 JS):

HTML
<header jade-region-drag>
  标题栏内容……
  <button jade-region-no-drag>可点击的按钮(挖洞)</button>
</header>

与旧 CSS -webkit-app-region: drag 的区别:右键不弹系统标题栏菜单。

多线程注意事项

  • JadeView 的 API 函数是线程安全的,可从火山工作线程调用
  • 事件 / IPC 回调可能来自库线程:回调里操作你自己的共享数据需自行加锁
  • 回调内避免阻塞(见上文 IPC 一节)

打包与分发

  • 静态链接,产物单 exe;前端资源经 @视窗.附属文件 复制或 JAPK 内置
  • 运行时依赖仅 WebView2 Runtime(Win11 自带;Win10 检测安装见官方 WebView2 安装指南)
  • 数据目录默认在 %LOCALAPPDATA% 下按应用标识划分,日志在 {数据目录}\logs路径常量.应用日志目录