From your previous post, I assume you want to resize multiple top-level windows of the same class instead of the same process.
To do that, you first need to know the class name of your targeted windows. You can use a tool like Inspect or Spy++.
Then, the easiest way to list all top-level windows with a specific class is to use EnumWindows
and GetClassName
. For each matched window, you'll want to save its title and handle. This way the user can choose the window based on the title, then you can use the associated handle to resize it.
Here's a complete example:
const Win32 = require('win32-api/promise');
const Win32Sync = require('win32-api');
const ffi = require('ffi-napi');
const W = require('win32-api').DTypes;
const User32 = Win32.User32.load(['EnumWindows', 'FindWindowExW', 'SetWindowPos']);
const User32Sync = Win32Sync.User32.load(['IsWindowVisible', 'GetClassNameW', 'GetWindowTextW']);
const SWP_NOMOVE = 0x0002, SWP_NOACTIVATE = 0x0010;
module.exports =
{
FindWindows: async function (className)
{
var windowsList = [];
const lpEnumFunc = ffi.Callback(W.BOOL, [W.HWND, W.LPARAM], (hWnd, lParam) =>
{
// EnumWindowsProc: https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms633498(v=vs.85)
if (!User32Sync.IsWindowVisible(hWnd))
{
// Ignore hidden windows
return true;
}
// Compare class names
const maxLen = 127;
const buf = Buffer.alloc(maxLen * 2);
const len = User32Sync.GetClassNameW(hWnd, buf, maxLen);
const wndClass = buf.toString('ucs2').replace(/\0+$/, '');
if (len && wndClass === className)
{
let title = '';
if(User32Sync.GetWindowTextW(hWnd, buf, maxLen))
{
title = buf.toString('ucs2').replace(/\0+$/, '');
}
windowsList.push({ title: title, hWnd: hWnd });
}
return true;
});
await User32.EnumWindows(lpEnumFunc, 0);
return windowsList;
},
ResizeWindow: async function (hWnd, width, height)
{
await User32.SetWindowPos(hWnd, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOACTIVATE);
}
};
However, this code won't work for you (at least as of now), because win32-api still doesn't include GetClassName
. But you can easily add it, just edit win32-api/src/lib/user32/api.ts
and recompile:
export interface Win32Fns
{
// ...
GetWindowTextW: (hWnd: M.HWND, lpString: M.LPCTSTR, nMaxCount: M.INT) => M.INT
GetClassNameW: (hWnd: M.HWND, lpString: M.LPCTSTR, nMaxCount: M.INT) => M.INT // <-- add this
// ...
}
export const apiDef: M.DllFuncs<Win32Fns> = {
// ...
GetWindowTextW: [W.INT, [W.HWND, W.LPTSTR, W.INT]],
GetClassNameW: [W.INT, [W.HWND, W.LPTSTR, W.INT]], // <-- add this
// ...
}
Result (full_example.zip):
