将焦点从Node-JS设置到Windows应用程序

我有一个在Windows上运行的NodeJS应用程序,当用户执行特定操作时,需要显示并将焦点切换到正在运行的Windows应用程序。 我一直在使用node-ffi包进行windows API调用,但一直无法使焦点切换。 这是我正在使用的代码。 它成功地得到了正在运行的Calculator应用程序的HWND,但是随后尝试将焦点切换到该HWND,并且它仅在有时才起作用:

var ffi = require('ffi'); var intPtr = ref.refType('long'); var user32 = new ffi.Library('user32', { 'FindWindowA': ['long', [ 'string', 'string']], 'SetForegroundWindow': ['bool', ['long']], 'BringWindowToTop': ['bool', ['long']], }); var winToSetOnTop = user32.FindWindowA(null,"calculator") var res = user32.ShowWindow(winToSetOnTop, 9); res = user32.SetForegroundWindow(winToSetOnTop); res = user32.BringWindowToTop(winToSetOnTop); 

这些命令的组合似乎与我所尝试过的最一致,但并不一直工作。 如果我想要将焦点切换到最小的窗口,它将始终popup到顶部。 如果窗口不是最小化的,而是在另一个窗口的后面,它将只会间歇显示。 我不知道如何始终如一地让运行的Windows应用程序始终移动到订单的顶部,即使它当前已经最小化了。

我已经制定了以下解决scheme,可以在任何情况下都能很好地实现上面的窗口。 首先它将得到一个正在运行的Calculator应用程序实例的窗口句柄,然后它将会把它放在最上面并且把它聚焦。

 var user32 = new ffi.Library('user32', { 'GetTopWindow': ['long', ['long']], 'FindWindowA': ['long', ['string', 'string']], 'SetActiveWindow': ['long', ['long']], 'SetForegroundWindow': ['bool', ['long']], 'BringWindowToTop': ['bool', ['long']], 'ShowWindow': ['bool', ['long', 'int']], 'SwitchToThisWindow': ['void', ['long', 'bool']], 'GetForegroundWindow': ['long', []], 'AttachThreadInput': ['bool', ['int', 'long', 'bool']], 'GetWindowThreadProcessId': ['int', ['long', 'int']], 'SetWindowPos': ['bool', ['long', 'long', 'int', 'int', 'int', 'int', 'uint']], 'SetFocus': ['long', ['long']] }); var kernel32 = new ffi.Library('Kernel32.dll', { 'GetCurrentThreadId': ['int', []] }); var winToSetOnTop = user32.FindWindowA(null, "calculator") var foregroundHWnd = user32.GetForegroundWindow() var currentThreadId = kernel32.GetCurrentThreadId() var windowThreadProcessId = user32.GetWindowThreadProcessId(foregroundHWnd, null) var showWindow = user32.ShowWindow(winToSetOnTop, 9) var setWindowPos1 = user32.SetWindowPos(winToSetOnTop, -1, 0, 0, 0, 0, 3) var setWindowPos2 = user32.SetWindowPos(winToSetOnTop, -2, 0, 0, 0, 0, 3) var setForegroundWindow = user32.SetForegroundWindow(winToSetOnTop) var attachThreadInput = user32.AttachThreadInput(windowThreadProcessId, currentThreadId, 0) var setFocus = user32.SetFocus(winToSetOnTop) var setActiveWindow = user32.SetActiveWindow(winToSetOnTop)