无边框自绘窗口
无边框窗口 + 前端自绘标题栏 + 拖动/控制按钮。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}