使用节点模块Win32 - API和节点模块ffi-napi,我能够成功调用Win32 API EnumWindows。
工作代码如下:
const { DStruct: DS, DTypes: W, U } = require('win32-api');
const user32 = U.load();
const ffi = require('ffi-napi');
const WndEnumProc = ffi.Callback(
W.BOOL, [W.HWND, W.LPARAM],
(hwnd, lparam) => {
console.log('First enumerated window is: ' + hwnd);
return 0;
}
);
user32.EnumWindows( WndEnumProc, 0 );
输出是(注意,我在回调中返回0以停止枚举):
第一个枚举窗口是:65914
现在,我想使用EnumWindows
的LPARAM参数来传递一个"指针"。到回调函数的自定义结构体
如果我使用C
,结构将是这样的:
struct EnumParams {
UINT uiMsg;
WPARAM wParam;
LPARAM lParam;
}
问题:如何声明,定义,传递和使用自定义结构与ffi回调?
What I tried:
const { DStruct: DS, DTypes: W, U } = require('win32-api');
const user32 = U.load();
const ffi = require('ffi-napi');
const ref = require('ref-napi');
const StructDi = require('ref-struct-di');
const Struct = StructDi(ref);
const EnumParams = Struct({
uiMsg: W.UINT,
wParam: W.WPARAM,
lParam: W.LPARAM
});
const WndEnumProc = ffi.Callback(
W.BOOL, [W.HWND, ref.refType(EnumParams)],
(hwnd, ep) => {
console.log('type of ep is: ' + typeof ep);
console.log('type of ep.uiMsg is: ' + typeof ep.uiMsg);
console.log('First enumerated window is: ' + hwnd);
return 0;
}
);
var EP = new EnumParams;
EP.uiMsg = 0;
EP.wApram = 0;
EP.lParam = 42;
user32.EnumWindows( WndEnumProc, EP.ref() );
输出:
type of ep is: object
type of ep.uiMsg is: undefined
First enumerated window is: 65914
正如你所看到的,我不能在回调中访问我的结构体的成员。也许这是我定义/使用…的方式
在win32-api
作者的帮助下,我现在有了一个工作版本:
const { DStruct: DS, DTypes: W, U } = require('win32-api');
const user32 = U.load();
const ffi = require('ffi-napi');
const ref = require('ref-napi');
const StructDi = require('ref-struct-di');
const Struct = StructDi(ref);
const EnumParams = Struct({
uiMsg: W.UINT,
wParam: W.WPARAM,
lParam: W.LPARAM
});
var EP = new EnumParams;
EP.uiMsg = 0;
EP.wParam = 0;
EP.lParam = 42;
const refType = EP.ref().ref().type;
const WndEnumProc = ffi.Callback(
W.BOOL, [W.HWND, W.LPARAM],
(hwnd, ep) => {
const buf = Buffer.alloc(4); // node 32 bits...
buf.writeInt32LE(ep, 0);
buf.type = refType;
const EPObject = buf.deref().deref();
console.log( 'EPObject.lParam is: ' + EPObject.lParam );
console.log('First enumerated window is: ' + hwnd);
return 0; // Stop enumeration at the first window
}
);
user32.EnumWindows( WndEnumProc, EP.ref().address() );
输出为:
EPObject.lParam is: 42
First enumerated window is: 196734