我正在开发一个firefox扩展,我需要关注其他程序。 window.focus()仅适用于其他firefox窗口。这可能吗?
答案 0 :(得分:0)
这与我在这里回答的另一个问题类似:xul:panel position on multiple monitors
在js-ctypes加载/使用的外部DLL的帮助下,我能够实现你想要的。为了操纵OS级别的窗口焦点,您需要能够做两件事:
find_window
javascript函数),window_focus
功能)。我发现找到窗口句柄的最简单方法是将窗口标题更改为可预测的不会与其他窗口标题冲突的内容(比如MD5总和为"your-app"+(new Date())
),然后枚举所有操作系统 - 级别窗口查找具有该标题的窗口(find_window
)。
一旦有了窗口句柄,就可以调用window_focus
(在下面定义)来聚焦操作系统级窗口。
Win32示例:
以下是将外部DLL绑定到JavaScript的基础知识。此示例仅涵盖Win32,但每个都适用相同的过程。
共有3个部分:
我在VS2010中构建了一个简单的GUI DLL项目,后面有两个文件&编译wmctrl.dll,具体取决于msvcr100.dll,并使用Dependency Walker查找DLL导出的“plain C”符号,供js-ctypes使用。
在特权JavaScript代码中(例如:在您的插件代码中):
// import js-ctypes
const {Cc,Ci,Cu} = require("chrome"); // you probably don't need this line.
var file=null, lib=null, ctypes = {};
Cu.import("resource://gre/modules/ctypes.jsm", ctypes);
var ctypes = ctypes.ctypes;
// build platform specific library path (yours will be named/located differently)
var filename = ctypes.libraryName("wmctrl");
var comp = "@mozilla.org/file/directory_service;1"; // read the docs for this!!!
var file = Cc[comp].getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile);
file.append("browser_code"); // a sub-folder
file.append(filename);
// get the JavaScript library interface (load the library)
var lib = ctypes.open(file.path);
// wmctrl_find_window: returing unsigned 32bit (long) "window handle"
// takes string "window title".
var find_window = lib.declare("?wmctrl_find_window@@YAKPAD@Z",
ctypes.stdcall_abi, ctypes.uint32_t,
ctypes.char.ptr);
// wmctrl_window_focus: takes unsigned 32bit (long) "window handle".
var window_focus = lib.declare("?wmctrl_window_focus@@YAXK@Z",
ctypes.stdcall_abi, ctypes.void_t,
ctypes.uint32_t);
wmctrldll.h
#ifdef WMCTRLDLL_EXPORTS
#define WMCTRLDLL_API __declspec(dllexport)
#else
#define WMCTRLDLL_API __declspec(dllimport)
#endif
WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title);
WMCTRLDLL_API void wmctrl_window_focus (unsigned long wid);
wmctrldll.cpp
typedef struct {
HWND hWnd;
char title[255];
} myWinSpec;
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) {
char String[255];
myWinSpec* to_find = (myWinSpec*) lParam;
// not a window
if (!hWnd) return TRUE;
// not visible
if (!IsWindowVisible(hWnd)) return TRUE;
// no window title
if (!GetWindowTextA(hWnd, (LPSTR)String, 255)) return TRUE;
// no title match
if (strcmp(String, to_find->title) != 0) return TRUE;
to_find->hWnd = hWnd;
return FALSE;
}
WMCTRLDLL_API void wmctrl_window_focus(unsigned long wid) {
SetForegroundWindow((HWND) wid);
}
WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title) {
myWinSpec to_find;
sprintf_s(to_find.title, sizeof(to_find.title), "%s", find_title);
to_find.hWnd = 0;
EnumWindows(EnumWindowsProc, (LPARAM)&to_find);
return (unsigned long) to_find.hWnd;
}
我也为Linux(X11)和Mac OS X做了这个,没有太多困难。