Using the node module win32-api and the node module ffi-napi, I am able to successfully call the Win32 API EnumWindows.
The working code is as follow:
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 );
The output is (note that I return 0 in the callback to stop the enumeration):
First enumerated window is: 65914
Now, I want to use the LPARAM parameter of EnumWindows
to pass a "pointer" to a custom struct to the callback.
If I was using C
, the structure would be like that:
struct EnumParams {
UINT uiMsg;
WPARAM wParam;
LPARAM lParam;
}
Question: How to declare, define, pass, and use a custom struct with a ffi callback?
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() );
Output:
type of ep is: object
type of ep.uiMsg is: undefined
First enumerated window is: 65914
As I you can see, I can't access member of my struct in the callback. Maybe it's the way I define/use...
CodePudding user response:
With help from the author of win32-api
, I now have a working version:
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() );
And the output is:
EPObject.lParam is: 42
First enumerated window is: 196734