refactor: 把 koffi 的 Win32 加载抽到共用模块
粘贴和光标读取共用同一次 user32/kernel32 加载,避免重复定义结构体。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1ae69ab95e
commit
640a92edff
2 files changed
+83
-52
No files matched your search
+2
-52
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const { loadWin32 } = require('./win32');
|
||||
|
||||
const INPUT_KEYBOARD = 1;
|
||||
const KEYEVENTF_KEYUP = 0x0002;
|
||||
const VK_CONTROL = 0x11;
|
||||
@@ -42,58 +44,6 @@ function writeSnapshot(clipboard, snap) {
|
||||
clipboard.write(payload);
|
||||
}
|
||||
|
||||
let win32 = null;
|
||||
|
||||
function loadWin32() {
|
||||
if (win32) return win32;
|
||||
if (process.platform !== 'win32') return null;
|
||||
const koffi = require('koffi');
|
||||
const user32 = koffi.load('user32.dll');
|
||||
const kernel32 = koffi.load('kernel32.dll');
|
||||
|
||||
const KEYBDINPUT = koffi.struct('KEYBDINPUT', {
|
||||
wVk: 'uint16_t',
|
||||
wScan: 'uint16_t',
|
||||
dwFlags: 'uint32_t',
|
||||
time: 'uint32_t',
|
||||
dwExtraInfo: 'uintptr_t',
|
||||
});
|
||||
const MOUSEINPUT = koffi.struct('MOUSEINPUT', {
|
||||
dx: 'long',
|
||||
dy: 'long',
|
||||
mouseData: 'uint32_t',
|
||||
dwFlags: 'uint32_t',
|
||||
time: 'uint32_t',
|
||||
dwExtraInfo: 'uintptr_t',
|
||||
});
|
||||
const HARDWAREINPUT = koffi.struct('HARDWAREINPUT', {
|
||||
uMsg: 'uint32_t',
|
||||
wParamL: 'uint16_t',
|
||||
wParamH: 'uint16_t',
|
||||
});
|
||||
const INPUT = koffi.struct('INPUT', {
|
||||
type: 'uint32_t',
|
||||
u: koffi.union({
|
||||
mi: MOUSEINPUT,
|
||||
ki: KEYBDINPUT,
|
||||
hi: HARDWAREINPUT,
|
||||
}),
|
||||
});
|
||||
|
||||
win32 = {
|
||||
koffi,
|
||||
INPUT,
|
||||
GetForegroundWindow: user32.func('void * __stdcall GetForegroundWindow()'),
|
||||
SetForegroundWindow: user32.func('bool __stdcall SetForegroundWindow(void *hWnd)'),
|
||||
AllowSetForegroundWindow: user32.func('bool __stdcall AllowSetForegroundWindow(uint32_t dwProcessId)'),
|
||||
GetWindowThreadProcessId: user32.func('uint32_t __stdcall GetWindowThreadProcessId(void *hWnd, _Out_ uint32_t *lpdwProcessId)'),
|
||||
AttachThreadInput: user32.func('bool __stdcall AttachThreadInput(uint32_t idAttach, uint32_t idAttachTo, bool fAttach)'),
|
||||
GetCurrentThreadId: kernel32.func('uint32_t __stdcall GetCurrentThreadId()'),
|
||||
SendInput: user32.func('unsigned int __stdcall SendInput(unsigned int cInputs, INPUT *pInputs, int cbSize)'),
|
||||
};
|
||||
return win32;
|
||||
}
|
||||
|
||||
function captureForeground() {
|
||||
try {
|
||||
const api = loadWin32();
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
'use strict';
|
||||
|
||||
let win32 = null;
|
||||
|
||||
function loadWin32() {
|
||||
if (win32) return win32;
|
||||
if (process.platform !== 'win32') return null;
|
||||
const koffi = require('koffi');
|
||||
const user32 = koffi.load('user32.dll');
|
||||
const kernel32 = koffi.load('kernel32.dll');
|
||||
|
||||
const KEYBDINPUT = koffi.struct('KEYBDINPUT', {
|
||||
wVk: 'uint16_t',
|
||||
wScan: 'uint16_t',
|
||||
dwFlags: 'uint32_t',
|
||||
time: 'uint32_t',
|
||||
dwExtraInfo: 'uintptr_t',
|
||||
});
|
||||
const MOUSEINPUT = koffi.struct('MOUSEINPUT', {
|
||||
dx: 'long',
|
||||
dy: 'long',
|
||||
mouseData: 'uint32_t',
|
||||
dwFlags: 'uint32_t',
|
||||
time: 'uint32_t',
|
||||
dwExtraInfo: 'uintptr_t',
|
||||
});
|
||||
const HARDWAREINPUT = koffi.struct('HARDWAREINPUT', {
|
||||
uMsg: 'uint32_t',
|
||||
wParamL: 'uint16_t',
|
||||
wParamH: 'uint16_t',
|
||||
});
|
||||
const INPUT = koffi.struct('INPUT', {
|
||||
type: 'uint32_t',
|
||||
u: koffi.union({
|
||||
mi: MOUSEINPUT,
|
||||
ki: KEYBDINPUT,
|
||||
hi: HARDWAREINPUT,
|
||||
}),
|
||||
});
|
||||
|
||||
// 64 位默认对齐:两个 DWORD 之后 HWND 从偏移 8 开始,末尾 RECT,共 72 字节。
|
||||
const RECT = koffi.struct('RECT', {
|
||||
left: 'long',
|
||||
top: 'long',
|
||||
right: 'long',
|
||||
bottom: 'long',
|
||||
});
|
||||
const POINT = koffi.struct('POINT', {
|
||||
x: 'long',
|
||||
y: 'long',
|
||||
});
|
||||
const GUITHREADINFO = koffi.struct('GUITHREADINFO', {
|
||||
cbSize: 'uint32_t',
|
||||
flags: 'uint32_t',
|
||||
hwndActive: 'void *',
|
||||
hwndFocus: 'void *',
|
||||
hwndCapture: 'void *',
|
||||
hwndMenuOwner: 'void *',
|
||||
hwndMoveSize: 'void *',
|
||||
hwndCaret: 'void *',
|
||||
rcCaret: RECT,
|
||||
});
|
||||
|
||||
win32 = {
|
||||
koffi,
|
||||
INPUT,
|
||||
GUITHREADINFO,
|
||||
GetForegroundWindow: user32.func('void * __stdcall GetForegroundWindow()'),
|
||||
SetForegroundWindow: user32.func('bool __stdcall SetForegroundWindow(void *hWnd)'),
|
||||
AllowSetForegroundWindow: user32.func('bool __stdcall AllowSetForegroundWindow(uint32_t dwProcessId)'),
|
||||
GetWindowThreadProcessId: user32.func('uint32_t __stdcall GetWindowThreadProcessId(void *hWnd, _Out_ uint32_t *lpdwProcessId)'),
|
||||
AttachThreadInput: user32.func('bool __stdcall AttachThreadInput(uint32_t idAttach, uint32_t idAttachTo, bool fAttach)'),
|
||||
GetCurrentThreadId: kernel32.func('uint32_t __stdcall GetCurrentThreadId()'),
|
||||
SendInput: user32.func('unsigned int __stdcall SendInput(unsigned int cInputs, INPUT *pInputs, int cbSize)'),
|
||||
GetGUIThreadInfo: user32.func('bool __stdcall GetGUIThreadInfo(uint32_t idThread, _Inout_ GUITHREADINFO *pgui)'),
|
||||
ClientToScreen: user32.func('bool __stdcall ClientToScreen(void *hWnd, _Inout_ POINT *lpPoint)'),
|
||||
};
|
||||
return win32;
|
||||
}
|
||||
|
||||
module.exports = { loadWin32 };
|
||||
Reference in new issue
Block a user