1.作用
实现窗体吸附功能,当窗体靠近某个应用边缘时,自动吸附到边缘,并且大小和边缘对齐
2.实现方式
使用js调用系统的user32.dll获取窗口的位置大小信息。
3.安装调用dll的库,目前用的比较好用的一个
npm install ffi-rs
4.electron主线程中使用
import {createPointer, DataType, define, open, restorePointer, unwrapPointer} from "ffi-rs";
open({
library: 'user32',
path: 'user32'
})
// 这里填写需要吸附的窗口名字
const SNAP_FORM_TITLE_ARR = ['千牛工作台', '接待中心']
// 通过窗体标题判断窗体要不要吸附
function isSnapForm(title: string) {
return SNAP_FORM_TITLE_ARR.some(it => title?.includes(it))
}
const user32 = define({
"GetWindowRect": {
library: "user32",
retType: DataType.Boolean,
paramsType: [DataType.I32, DataType.External]
},
"GetWindowTextW": {
library: "user32",
retType: DataType.I32,
paramsType: [DataType.I32, DataType.U8Array, DataType.I32]
},
"GetForegroundWindow": {
library: "user32",
retType: DataType.I32,
paramsType: []
},
})
// 窗体矩形类型
const rectType = {
left: DataType.I32,
top: DataType.I32,
right: DataType.I32,
bottom: DataType.I32
}
const rect = {
left: 0,
top: 0,
right: 0,
bottom: 0
}
const rectPointer = createPointer({
paramsType: [rectType],
paramsValue: [rect]
})
let interval: NodeJS.Timeout;
// 吸附和取消吸附
export function monitorWindow(cb: (res: typeof rect) => void) {
if (interval) {
clearInterval(interval)
interval = null
} else {
interval = setInterval(() => {
const hwnd = user32.GetForegroundWindow([]);
const titleBuffer = Buffer.alloc(200)
user32.GetWindowTextW([hwnd, titleBuffer, titleBuffer.length])
const title = titleBuffer.toString('utf16le')
if (isSnapForm(title)) {
user32.GetWindowRect([hwnd, unwrapPointer(rectPointer)[0]])
const restoreData = restorePointer({
paramsValue: rectPointer,
retType: [rectType]
})
cb(restoreData[0])
}
}, 16)
// 16ms相对丝滑一点
}
}
const win = new BrowserWindow({
...
})
// 屏幕缩放因子 -> 1.0 1.5(适配不同的显示器缩放布局),如果还要适配扩展屏,需要自己实现一下
const scale = screen.getPrimaryDisplay().scale;
monitorWindow((rect) => {
const {left, top, right, bottom} = rect;
win.setSize(MAIN_WIN_WIDTH, Math.floor((bottom - top) / scaleFactor));
win.setPosition(Math.ceil(left / scale - MAIN_WIN_WIDTH), Math.ceil(top / scale));
win.setAlwaysOnTop(true);
})
本文使用MdSync工具发布!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。