Home > Net >  How to use a custom struct with EnumWindows in the win32-api node module
How to use a custom struct with EnumWindows in the win32-api node module

Time:06-23

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
  • Related