Skip to content

无边框自绘窗口

无边框窗口 + 前端自绘标题栏 + 拖动/控制按钮。webview 内置槽,开箱即用。

1. C++:开 frameless + 用 WindowTem

cpp
auto win = app.createWindow(
    Window::opts()
        .title(L"my app")
        .size(1000, 700)
        .frameless(true)                          // 关键:去掉系统边框
        .url(L"src/assets/html/index.html")
);

auto tem = std::make_shared<webview::WindowTem>(win);
tem->start();   // 自动绑 handleWindowBtn / moveWindow 两槽

WindowTem 构造时自动绑两个固定通道:

通道干什么
handleWindowBtn{type:"min"|"close"|"topic"} → 最小化/关闭/置顶切换
moveWindow{x,y} → 按位移拖动窗口

2. 前端:自绘标题栏

标题栏区可拖动,右上三按钮调固定通道:

vue
<template>
  <div class="titlebar" @mousedown="startDrag">
    <span class="title">my app</span>
    <div class="btns">
      <button @click="btn('min')">—</button>
      <button @click="btn('topic')">▲</button>
      <button @click="btn('close')">✕</button>
    </div>
  </div>
</template>

<script setup>
const startDrag = () => {
  // 触发拖动:发鼠标初始位移(0,0)即可进入拖动循环
  bridge.call('moveWindow', { x: 0, y: 0 })
}

const btn = (type) => bridge.call('handleWindowBtn', { type })
</script>

<style>
.titlebar {
  height: 32px; display: flex; align-items: center;
  -webkit-app-region: drag;            /* 可选:CSS 声明拖动区 */
  user-select: none;
}
.btns button { -webkit-app-region: no-drag; }
</style>

实现细节

具体拖动协议(mousedown→mousemove 累积位移→moveWindow)取决于 moveWindow 的实现。典型模式:标题栏 mousedown 记起点,mousemove 算 delta 调 bridge.call('moveWindow', {x: dx, y: dy})。参考 webviewTest.exe demo。

3. 阴影与圆角

无边框默认无系统阴影。需阴影时用 shadow_window(框架提供,#include "webview/shadow_window.hpp")或 CSS box-shadow。

完整流程

frameless(true) + WindowTem
  → 自动绑 handleWindowBtn / moveWindow
前端标题栏 mousedown → moveWindow 拖
前端按钮 click → handleWindowBtn {min|close|topic}

下一步