使用 firefox 插件将 firefox window 置于最前面
bring firefox window to the front using firefox addon
我想在我的 firefox addon
上使用特定功能 运行 时关注 firefox。我创建了一个 .vbs 文件,它可以关注 firefox
[置于顶部] 然后我使用 nsIProcess
.like this
执行该 exe
file.initWithPath("C:\Users\madhawax\Documents\focusFirefox.vbs");
var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
process.init(file);
process.run(false, args, args.length);
它可以工作 fine.but 现在出于某种原因,我想直接从插件代码中聚焦 Firefox,而不需要另一个应用程序的帮助。我读过 firefox windows
api 但我还是找不到焦点 window.what 我想问的是如何从插件代码中焦点浏览器。
编辑..
这是我用来关注 firefox 的代码。
focusFirefox.vbs
Set wshShell = CreateObject("WScript.Shell")
wshShell.AppActivate("Firefox")
这些解决方案使用 js-ctypes winapi。这是一个 Windows 解决方案。 OSX 和 Linux 没有这个问题,那里很容易窃取焦点。
如果我们只做SetForegroundWindow
winapi方法就容易了,但是调用这个方法的进程必须有用户焦点。如果没有,那么它什么都不做,所以这里是强制它的方法:
附加到线程方法(推荐方法)
此方法执行以下操作:
- 获取当前在前台的window
- 如果 none 找到,常规
SetForegroundWindow
将起作用,所以它会这样做并退出
- 如果window在前台找到它然后获取其线程的ID
- 然后将其与当前 firefox 的线程 ID(目标 windows 线程)进行比较
- 如果相同则使用常规
SetForegroundWindow
并退出
- 如果不相同,则使用
AttachThreadInput
将 firefox 的线程附加到当前前台的线程 window
- 如果第 6 步调用失败,则放弃并退出该函数,并抛出错误
- 如果第 6 步中的调用没有失败,那么它将调用
SetForegroundWindow
,因为它现在可以工作了
- 然后它会撤消在第 6 步中完成的附件,因此如果您现在进行
SetForegroundWindow
调用,它将像往常一样失败
我想不出 AttachThreadInput
会失败的原因,但如果失败了,那是此方法唯一不万无一失的部分。如果有人知道为什么会失败,请针对该失败原因分享解决方案。但是,我将下面的 SetCursorPos
方法留作紧急备用。
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/ctypes.jsm');
if (ctypes.voidptr_t.size == 4 /* 32-bit */ ) {
var is64bit = false;
} else if (ctypes.voidptr_t.size == 8 /* 64-bit */ ) {
var is64bit = true;
} else {
throw new Error('huh??? not 32 or 64 bit?!?!');
}
var user32 = ctypes.open('user32.dll');
var GetForegroundWindow = user32.declare('GetForegroundWindow', ctypes.winapi_abi,
ctypes.voidptr_t // return
);
var DWORD = ctypes.uint32_t;
var LPDWORD = DWORD.ptr;
var GetWindowThreadProcessId = user32.declare('GetWindowThreadProcessId', ctypes.winapi_abi,
DWORD, // return
ctypes.voidptr_t, // hWnd
LPDWORD // lpdwProcessId
);
var AttachThreadInput = user32.declare('AttachThreadInput', ctypes.winapi_abi,
ctypes.bool, // return
DWORD, // idAttach
DWORD, // idAttachTo
ctypes.bool // fAttach
);
var SetForegroundWindow = user32.declare('SetForegroundWindow', ctypes.winapi_abi,
ctypes.bool, // return BOOL
ctypes.voidptr_t // HWND
);
function forceFocus() {
var hToDOMWindow = Services.wm.getMostRecentWindow('navigator:browser');
if (!hToDOMWindow) {
throw new Error('No browser window found');
}
var hToBaseWindow = hToDOMWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIBaseWindow);
var hToString = hToBaseWindow.nativeHandle;
var hTo = ctypes.voidptr_t(ctypes.UInt64(hToString));
var hFrom = GetForegroundWindow();
if (hFrom.isNull()) {
var rez_SetSetForegroundWindow = SetForegroundWindow(hTo);
console.log('rez_SetSetForegroundWindow:', rez_SetSetForegroundWindow);
return true;
}
if (hTo.toString() == hFrom.toString()) {
console.log('window is already focused');
return true;
}
var pid = GetWindowThreadProcessId(hFrom, null);
console.info('pid:', pid);
var _threadid = GetWindowThreadProcessId(hTo, null); // _threadid is thread of my firefox id, and hTo is that of my firefox id so this is possible to do
console.info('_threadid:', _threadid);
if (pid == _threadid) {
var rez_SetSetForegroundWindow = SetForegroundWindow(hTo);
console.log('rez_SetSetForegroundWindow:', rez_SetSetForegroundWindow);
return true;
}
var rez_AttachThreadInput = AttachThreadInput(_threadid, pid, true)
console.info('rez_AttachThreadInput:', rez_AttachThreadInput);
if (!rez_AttachThreadInput) {
throw new Error('failed to attach thread input');
}
var rez_SetSetForegroundWindow = SetForegroundWindow(hTo);
console.log('rez_SetSetForegroundWindow:', rez_SetSetForegroundWindow);
var rez_AttachThreadInput = AttachThreadInput(_threadid, pid, false)
console.info('rez_AttachThreadInput:', rez_AttachThreadInput);
}
setTimeout(function() {
forceFocus();
user32.close();
}, 5000);
窃取然后恢复光标位置的方法(不推荐的方法 - 不是万无一失的,因为它模拟点击 - 如果用户在全屏模式下 window,它可能会点击类似 link 的东西,并且link 位于 window)
的位置 0,0
这是一个使用 js-ctypes 且仅适用于 Windows 操作系统的解决方案,它执行以下操作:
- 将目标 window 设置为 "always on top"(但焦点尚未在 window 中)
- 获取当前光标位置
- 将光标位置设置到 window
的左上角
- 点击以聚焦
- 将光标位置恢复到原来的位置
- 将 window 设置回正常(不是 "always on top")
它有一个问题,即 SendInput
中合成鼠标点击的 x 和 y 坐标没有得到尊重,这就是为什么我不得不使用 SetCursorPos
,在未来的修订中我想解决这个问题,这样它就不会使用 SetCursorPos
,因为移动用户的鼠标对用户来说很烦人,但好处远远超过轻微的烦恼,因为给予 window 焦点非常重要,我是暂时接受这个SetCursorPos
方法,因为我做了一个"restore cursor position to before stealing",所以这里是:
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/ctypes.jsm');
function myFocus() {
//////// START Ctypes DECLARES
if (ctypes.voidptr_t.size == 4 /* 32-bit */ ) {
var is64bit = false;
} else if (ctypes.voidptr_t.size == 8 /* 64-bit */ ) {
var is64bit = true;
} else {
throw new Error('huh??? not 32 or 64 bit?!?!');
}
var user32 = ctypes.open('user32.dll');
var SetWindowPos = user32.declare('SetWindowPos', ctypes.winapi_abi,
ctypes.bool, //return
ctypes.voidptr_t, //hwnd
ctypes.voidptr_t, //hWndInsertAfter
ctypes.int, //X
ctypes.int, //Y
ctypes.int, //cx
ctypes.int, //cy
ctypes.unsigned_int //uFlags
);
var RECT = ctypes.StructType('_RECT', [
{left: ctypes.long},
{top: ctypes.long},
{right: ctypes.long},
{bottom: ctypes.long}
]);
var LPRECT = RECT.ptr;
var GetWindowRect = user32.declare('GetWindowRect', ctypes.winapi_abi,
ctypes.bool, // return
ctypes.voidptr_t, // hwnd
LPRECT // lpRect
);
var SetCursorPos = user32.declare('SetCursorPos', ctypes.winapi_abi,
ctypes.bool, // return
ctypes.int, // x
ctypes.int // y
);
var POINT = ctypes.StructType('_tagPoint', [
{x: ctypes.long},
{y: ctypes.long}
]);
var LPPOINT = POINT.ptr;
var GetCursorPos = user32.declare('GetCursorPos', ctypes.winapi_abi,
ctypes.bool, // return
LPPOINT // lpPoint
);
// send mouse stuff
var ULONG_PTR = is64bit ? ctypes.uint64_t : ctypes.unsigned_long;
var DWORD = ctypes.uint32_t;
var MOUSEINPUT = ctypes.StructType('tagMOUSEINPUT', [
{'dx': ctypes.long},
{'dy': ctypes.long},
{'mouseData': DWORD},
{'dwFlags': DWORD},
{'time': ULONG_PTR},
{'dwExtraInfo': DWORD}
]);
var INPUT = ctypes.StructType('tagINPUT', [
{'type': DWORD},
{'mi': MOUSEINPUT} // union, pick which one you want, we want keyboard input
]);
var LPINPUT = INPUT.ptr;
var SendInput = user32.declare('SendInput', ctypes.winapi_abi, ctypes.unsigned_int, ctypes.unsigned_int, LPINPUT, ctypes.int);
var INPUT_MOUSE = 0;
var MOUSEEVENTF_LEFTDOWN = 2;
var MOUSEEVENTF_LEFTUP = 4;
var MOUSEEVENTF_ABSOLUTE = 0x8000;
// end send mouse stuff
var HWND_TOP = ctypes.voidptr_t(-1); //ctypes.cast(ctypes.int(-1), ctypes.voidptr_t);
var HWND_NOTOPMOST = ctypes.voidptr_t(-2);
var SWP_NOMOVE = 2;
var SWP_NOSIZE = 1;
//////// END Ctypes DECLARES
// pick a one of our navigator:browser firefox windows to focus
var browserWindow = Services.wm.getMostRecentWindow('navigator:browser');
if (!browserWindow) {
throw new Error('No browser window found');
}
// convert our DOMWindow to a HWND
var baseWindow = browserWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIBaseWindow);
var hwndString = baseWindow.nativeHandle;
var hwnd = ctypes.voidptr_t(ctypes.UInt64(hwndString));
browserWindow.focus(); // this is important, withou this, i dont know why, but the window will not become "always on top" from the SetWindowPos code on the next line
var rez_SetWindowPos = SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
console.log('rez_SetWindowPos:', rez_SetWindowPos);
var myRect = RECT();
var rez_GetWindowRect = GetWindowRect(hwnd, myRect.address());
console.log('rez_SetWindowPos:', rez_SetWindowPos);
var myRectLeft = parseInt(myRect.left.toString());
var myRectTop = parseInt(myRect.top.toString());
console.log('myRect.left', myRectLeft);
console.log('myRect.top', myRectTop);
var myPoint = POINT();
var rez_GetCursorPos = GetCursorPos(myPoint.address());
console.log('rez_GetCursorPos:', rez_GetCursorPos);
var myPointX = parseInt(myPoint.x.toString());
var myPointY = parseInt(myPoint.y.toString());
console.log('myPoint.x', myPointX);
console.log('myPoint.y', myPointY);
var rez_SetCursorPos = SetCursorPos(myRect.left, myRect.top);
console.log('rez_SetWindowPos:', rez_SetWindowPos);
// may need to wait for the window to come to top
// send click - i dont know why but the x and y coords of these send clicks is not being respected, it is just clicking where the mouse is, so im having to use SetCursorPos as temp hack
var js_pInputs = [
INPUT(INPUT_MOUSE, MOUSEINPUT(myRectLeft, myRectTop, 0, MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE, 0, 0)),
INPUT(INPUT_MOUSE, MOUSEINPUT(myRectLeft, myRectTop, 0, MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE, 0, 0))
];
var pInputs = INPUT.array()(js_pInputs);
var rez_SI = SendInput(pInputs.length, pInputs, INPUT.size);
console.log('rez_SI:', rez_SI.toString());
// end send click
var rez_SetCursorPos = SetCursorPos(myPoint.x, myPoint.y);
console.log('rez_SetWindowPos:', rez_SetWindowPos);
var rez_SetWindowPos = SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
console.log('rez_SetWindowPos:', rez_SetWindowPos);
user32.close();
}
setTimeout(function() {
myFocus();
}, 5000);
这是需要的方法,因为如果调用它的进程不是当前聚焦的进程,SetForegroundWindow
什么都不做。
经过测试,即使将另一个 window 设置为 "always on top" 也能正常工作,但因为另一个 window 始终位于顶部,所以在聚焦此 window.
我想在我的 firefox addon
上使用特定功能 运行 时关注 firefox。我创建了一个 .vbs 文件,它可以关注 firefox
[置于顶部] 然后我使用 nsIProcess
.like this
file.initWithPath("C:\Users\madhawax\Documents\focusFirefox.vbs");
var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
process.init(file);
process.run(false, args, args.length);
它可以工作 fine.but 现在出于某种原因,我想直接从插件代码中聚焦 Firefox,而不需要另一个应用程序的帮助。我读过 firefox windows
api 但我还是找不到焦点 window.what 我想问的是如何从插件代码中焦点浏览器。
编辑..
这是我用来关注 firefox 的代码。
focusFirefox.vbs
Set wshShell = CreateObject("WScript.Shell")
wshShell.AppActivate("Firefox")
这些解决方案使用 js-ctypes winapi。这是一个 Windows 解决方案。 OSX 和 Linux 没有这个问题,那里很容易窃取焦点。
如果我们只做SetForegroundWindow
winapi方法就容易了,但是调用这个方法的进程必须有用户焦点。如果没有,那么它什么都不做,所以这里是强制它的方法:
附加到线程方法(推荐方法)
此方法执行以下操作:
- 获取当前在前台的window
- 如果 none 找到,常规
SetForegroundWindow
将起作用,所以它会这样做并退出 - 如果window在前台找到它然后获取其线程的ID
- 然后将其与当前 firefox 的线程 ID(目标 windows 线程)进行比较
- 如果相同则使用常规
SetForegroundWindow
并退出 - 如果不相同,则使用
AttachThreadInput
将 firefox 的线程附加到当前前台的线程 window - 如果第 6 步调用失败,则放弃并退出该函数,并抛出错误
- 如果第 6 步中的调用没有失败,那么它将调用
SetForegroundWindow
,因为它现在可以工作了 - 然后它会撤消在第 6 步中完成的附件,因此如果您现在进行
SetForegroundWindow
调用,它将像往常一样失败
我想不出 AttachThreadInput
会失败的原因,但如果失败了,那是此方法唯一不万无一失的部分。如果有人知道为什么会失败,请针对该失败原因分享解决方案。但是,我将下面的 SetCursorPos
方法留作紧急备用。
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/ctypes.jsm');
if (ctypes.voidptr_t.size == 4 /* 32-bit */ ) {
var is64bit = false;
} else if (ctypes.voidptr_t.size == 8 /* 64-bit */ ) {
var is64bit = true;
} else {
throw new Error('huh??? not 32 or 64 bit?!?!');
}
var user32 = ctypes.open('user32.dll');
var GetForegroundWindow = user32.declare('GetForegroundWindow', ctypes.winapi_abi,
ctypes.voidptr_t // return
);
var DWORD = ctypes.uint32_t;
var LPDWORD = DWORD.ptr;
var GetWindowThreadProcessId = user32.declare('GetWindowThreadProcessId', ctypes.winapi_abi,
DWORD, // return
ctypes.voidptr_t, // hWnd
LPDWORD // lpdwProcessId
);
var AttachThreadInput = user32.declare('AttachThreadInput', ctypes.winapi_abi,
ctypes.bool, // return
DWORD, // idAttach
DWORD, // idAttachTo
ctypes.bool // fAttach
);
var SetForegroundWindow = user32.declare('SetForegroundWindow', ctypes.winapi_abi,
ctypes.bool, // return BOOL
ctypes.voidptr_t // HWND
);
function forceFocus() {
var hToDOMWindow = Services.wm.getMostRecentWindow('navigator:browser');
if (!hToDOMWindow) {
throw new Error('No browser window found');
}
var hToBaseWindow = hToDOMWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIBaseWindow);
var hToString = hToBaseWindow.nativeHandle;
var hTo = ctypes.voidptr_t(ctypes.UInt64(hToString));
var hFrom = GetForegroundWindow();
if (hFrom.isNull()) {
var rez_SetSetForegroundWindow = SetForegroundWindow(hTo);
console.log('rez_SetSetForegroundWindow:', rez_SetSetForegroundWindow);
return true;
}
if (hTo.toString() == hFrom.toString()) {
console.log('window is already focused');
return true;
}
var pid = GetWindowThreadProcessId(hFrom, null);
console.info('pid:', pid);
var _threadid = GetWindowThreadProcessId(hTo, null); // _threadid is thread of my firefox id, and hTo is that of my firefox id so this is possible to do
console.info('_threadid:', _threadid);
if (pid == _threadid) {
var rez_SetSetForegroundWindow = SetForegroundWindow(hTo);
console.log('rez_SetSetForegroundWindow:', rez_SetSetForegroundWindow);
return true;
}
var rez_AttachThreadInput = AttachThreadInput(_threadid, pid, true)
console.info('rez_AttachThreadInput:', rez_AttachThreadInput);
if (!rez_AttachThreadInput) {
throw new Error('failed to attach thread input');
}
var rez_SetSetForegroundWindow = SetForegroundWindow(hTo);
console.log('rez_SetSetForegroundWindow:', rez_SetSetForegroundWindow);
var rez_AttachThreadInput = AttachThreadInput(_threadid, pid, false)
console.info('rez_AttachThreadInput:', rez_AttachThreadInput);
}
setTimeout(function() {
forceFocus();
user32.close();
}, 5000);
窃取然后恢复光标位置的方法(不推荐的方法 - 不是万无一失的,因为它模拟点击 - 如果用户在全屏模式下 window,它可能会点击类似 link 的东西,并且link 位于 window)
的位置 0,0这是一个使用 js-ctypes 且仅适用于 Windows 操作系统的解决方案,它执行以下操作:
- 将目标 window 设置为 "always on top"(但焦点尚未在 window 中)
- 获取当前光标位置
- 将光标位置设置到 window 的左上角
- 点击以聚焦
- 将光标位置恢复到原来的位置
- 将 window 设置回正常(不是 "always on top")
它有一个问题,即 SendInput
中合成鼠标点击的 x 和 y 坐标没有得到尊重,这就是为什么我不得不使用 SetCursorPos
,在未来的修订中我想解决这个问题,这样它就不会使用 SetCursorPos
,因为移动用户的鼠标对用户来说很烦人,但好处远远超过轻微的烦恼,因为给予 window 焦点非常重要,我是暂时接受这个SetCursorPos
方法,因为我做了一个"restore cursor position to before stealing",所以这里是:
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/ctypes.jsm');
function myFocus() {
//////// START Ctypes DECLARES
if (ctypes.voidptr_t.size == 4 /* 32-bit */ ) {
var is64bit = false;
} else if (ctypes.voidptr_t.size == 8 /* 64-bit */ ) {
var is64bit = true;
} else {
throw new Error('huh??? not 32 or 64 bit?!?!');
}
var user32 = ctypes.open('user32.dll');
var SetWindowPos = user32.declare('SetWindowPos', ctypes.winapi_abi,
ctypes.bool, //return
ctypes.voidptr_t, //hwnd
ctypes.voidptr_t, //hWndInsertAfter
ctypes.int, //X
ctypes.int, //Y
ctypes.int, //cx
ctypes.int, //cy
ctypes.unsigned_int //uFlags
);
var RECT = ctypes.StructType('_RECT', [
{left: ctypes.long},
{top: ctypes.long},
{right: ctypes.long},
{bottom: ctypes.long}
]);
var LPRECT = RECT.ptr;
var GetWindowRect = user32.declare('GetWindowRect', ctypes.winapi_abi,
ctypes.bool, // return
ctypes.voidptr_t, // hwnd
LPRECT // lpRect
);
var SetCursorPos = user32.declare('SetCursorPos', ctypes.winapi_abi,
ctypes.bool, // return
ctypes.int, // x
ctypes.int // y
);
var POINT = ctypes.StructType('_tagPoint', [
{x: ctypes.long},
{y: ctypes.long}
]);
var LPPOINT = POINT.ptr;
var GetCursorPos = user32.declare('GetCursorPos', ctypes.winapi_abi,
ctypes.bool, // return
LPPOINT // lpPoint
);
// send mouse stuff
var ULONG_PTR = is64bit ? ctypes.uint64_t : ctypes.unsigned_long;
var DWORD = ctypes.uint32_t;
var MOUSEINPUT = ctypes.StructType('tagMOUSEINPUT', [
{'dx': ctypes.long},
{'dy': ctypes.long},
{'mouseData': DWORD},
{'dwFlags': DWORD},
{'time': ULONG_PTR},
{'dwExtraInfo': DWORD}
]);
var INPUT = ctypes.StructType('tagINPUT', [
{'type': DWORD},
{'mi': MOUSEINPUT} // union, pick which one you want, we want keyboard input
]);
var LPINPUT = INPUT.ptr;
var SendInput = user32.declare('SendInput', ctypes.winapi_abi, ctypes.unsigned_int, ctypes.unsigned_int, LPINPUT, ctypes.int);
var INPUT_MOUSE = 0;
var MOUSEEVENTF_LEFTDOWN = 2;
var MOUSEEVENTF_LEFTUP = 4;
var MOUSEEVENTF_ABSOLUTE = 0x8000;
// end send mouse stuff
var HWND_TOP = ctypes.voidptr_t(-1); //ctypes.cast(ctypes.int(-1), ctypes.voidptr_t);
var HWND_NOTOPMOST = ctypes.voidptr_t(-2);
var SWP_NOMOVE = 2;
var SWP_NOSIZE = 1;
//////// END Ctypes DECLARES
// pick a one of our navigator:browser firefox windows to focus
var browserWindow = Services.wm.getMostRecentWindow('navigator:browser');
if (!browserWindow) {
throw new Error('No browser window found');
}
// convert our DOMWindow to a HWND
var baseWindow = browserWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIBaseWindow);
var hwndString = baseWindow.nativeHandle;
var hwnd = ctypes.voidptr_t(ctypes.UInt64(hwndString));
browserWindow.focus(); // this is important, withou this, i dont know why, but the window will not become "always on top" from the SetWindowPos code on the next line
var rez_SetWindowPos = SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
console.log('rez_SetWindowPos:', rez_SetWindowPos);
var myRect = RECT();
var rez_GetWindowRect = GetWindowRect(hwnd, myRect.address());
console.log('rez_SetWindowPos:', rez_SetWindowPos);
var myRectLeft = parseInt(myRect.left.toString());
var myRectTop = parseInt(myRect.top.toString());
console.log('myRect.left', myRectLeft);
console.log('myRect.top', myRectTop);
var myPoint = POINT();
var rez_GetCursorPos = GetCursorPos(myPoint.address());
console.log('rez_GetCursorPos:', rez_GetCursorPos);
var myPointX = parseInt(myPoint.x.toString());
var myPointY = parseInt(myPoint.y.toString());
console.log('myPoint.x', myPointX);
console.log('myPoint.y', myPointY);
var rez_SetCursorPos = SetCursorPos(myRect.left, myRect.top);
console.log('rez_SetWindowPos:', rez_SetWindowPos);
// may need to wait for the window to come to top
// send click - i dont know why but the x and y coords of these send clicks is not being respected, it is just clicking where the mouse is, so im having to use SetCursorPos as temp hack
var js_pInputs = [
INPUT(INPUT_MOUSE, MOUSEINPUT(myRectLeft, myRectTop, 0, MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE, 0, 0)),
INPUT(INPUT_MOUSE, MOUSEINPUT(myRectLeft, myRectTop, 0, MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE, 0, 0))
];
var pInputs = INPUT.array()(js_pInputs);
var rez_SI = SendInput(pInputs.length, pInputs, INPUT.size);
console.log('rez_SI:', rez_SI.toString());
// end send click
var rez_SetCursorPos = SetCursorPos(myPoint.x, myPoint.y);
console.log('rez_SetWindowPos:', rez_SetWindowPos);
var rez_SetWindowPos = SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
console.log('rez_SetWindowPos:', rez_SetWindowPos);
user32.close();
}
setTimeout(function() {
myFocus();
}, 5000);
这是需要的方法,因为如果调用它的进程不是当前聚焦的进程,SetForegroundWindow
什么都不做。
经过测试,即使将另一个 window 设置为 "always on top" 也能正常工作,但因为另一个 window 始终位于顶部,所以在聚焦此 window.