2016-09-09 18 views
6

WindowsでNodeJSアプリケーションを実行しているときに、ユーザーが特定のアクションを実行したときに、実行中のWindowsアプリケーションにフォーカスを切り替えて表示する必要があります。私はWindows API呼び出しを行うためにnode-ffiパッケージを使用していますが、一貫してフォーカスを切り替えることができませんでした。ここに私が使用しているコードがあります。それが正常に実行されている電卓アプリのHWNDを取得しますが、そのHWNDにフォーカスを切り替えしようとすると、それだけで、時には作品:Node-JSからWindowsアプリケーションにフォーカスを設定

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); 

このコマンドの組み合わせが最も一貫し、私が試してみましたものの動作しているようですが、それは常に動作しません。フォーカスを切り替えるウィンドウが最小化されている場合、ウィンドウは常にトップにポップアップします。ウィンドウが最小化されずに別のウィンドウのすぐ後ろにある場合、断続的にしか表示されません。私は、たとえそれが現在最小化されていても、実行中のウィンドウアプリケーションを常にオーダーの先頭に移動させる方法を確実にはわかりません。

+0

あなたは両方とも、最小化されたウィンドウでは常に機能し、一貫して動作しないと言います。どちらが本当ですか? – IInspectable

+0

エラーをチェックしません。 SetForegroundWindowのドキュメント、特に条件のリストを読んでください。 –

+0

@IInspectable常に最小化されたウィンドウを上部に表示します。ウィンドウが最小化されておらず、別のウィンドウの後ろにある場合、ウィンドウは断続的に上に移動します。 – KeithTheBiped

答えて

7

私はすべての状況でうまく動作し、ウィンドウを一番上に持ってくる以下の解決策を見つけました。まず、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) 
+0

user32 apiについてもっと知りたいのですが? –

+0

@PauloHenrique Wikiのエントリhttps://en.wikipedia.org/wiki/Windows_USERは、user32.dllに関するハイレベルの情報を少し提供します。詳細については、Windows APIのMSDNを参照してください。私のソリューションで使用されているほとんどの機能に関するドキュメントは、「Windows」セクションにあります。https://msdn.microsoft.com/en-us/library/windows/desktop/ff468919(v=vs.85).aspx 。そうでなければ、WINAPIプログラミングは深い暗い穴であり、詳細については、いくつかのWindows OSの概念、データ構造などの概要を知るための入門ガイドがあります。 – KeithTheBiped

+0

提供する価値'FindWindowA'はプロセスのTITLEです。 – Luke

関連する問題