2016-09-09 3 views
6

사용자가 특정 작업을 수행 할 때 Windows 응용 프로그램에 포커스를 표시하고 전환해야하는 Windows에서 실행되는 NodeJS 응용 프로그램이 있습니다. 나는 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

저는 모든 상황에서 창을 맨 위로 가져 오는 다음과 같은 솔루션을 개발했습니다. 먼저 계산기 응용 프로그램의 실행중인 인스턴스에 창 핸들을 가져다가 최상위로 가져와 초점을 맞 춥니 다.

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 위키 항목 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