13

ユーザーが特定のアクションを実行したときに、実行中の Windows アプリケーションを表示してフォーカスを切り替える必要がある Windows 上で実行されている NodeJS アプリケーションがあります。node-ffi パッケージを使用して Windows API 呼び出しを行っていますが、一貫してフォーカスを切り替えることができませんでした。これが私が使用しているコードです。実行中の電卓アプリの 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);   

このコマンドの組み合わせは、私が試したものの中で最も一貫して機能するようですが、常に機能するとは限りません。フォーカスを切り替えたいウィンドウが最小化されている場合、常に一番上に表示されます。ウィンドウが最小化されておらず、別のウィンドウのすぐ後ろにある場合、断続的にしか表示されません。現在最小化されている場合でも、実行中の Windows アプリケーションを常に順序の一番上に移動させる方法がわかりません。

4

1 に答える 1

17

ウィンドウを一番上に表示するために、すべての状況でうまく機能する次の解決策を考え出しました。最初に、電卓アプリケーションの実行中のインスタンスへのウィンドウ ハンドルを取得し、次にそれを一番上に移動してフォーカスします。

var ffi = require('ffi-napi')

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)
于 2016-09-20T22:06:03.523 に答える