面向 Web 还是私有 Intranet?
窗口管理取决于浏览器和操作系统。HTML 和 ECMAscript 对此无话可说。
如果这是针对面向公众的网站,那么请不要打扰 - 正如他们所说,“不要破坏网络”。
但我真的很想!
如果这是针对某种严格管理(例如 Intranet)的应用程序,那么您将需要求助于编写插件/扩展。如果您可以将自己限制在单个浏览器和平台上,那肯定会更容易。
编辑:Win32 上的 Firefox 示例...
此解决方案用作 Firefox 的自定义插件,它在jsctypes
内部使用加载 Win32 DLL。JavaScript 函数已公开,window_focus()
可以执行您想要的操作。
此解决方案有 3 个部分:
- 用于加载/绑定 Win32 API 的特权 JavaScript 代码
- 我们外部 DLL 的 CPP 头文件
- 我们外部 DLL 的 CPP 源文件
我在 MSVC++ 中构建了一个简单的 GUI DLL 项目,其中包含后两个文件并编译wmctrl.dll
,具体取决于msvcr100.dll
,并使用Dependency Walker查找 DLL 导出的“普通 C”符号以供 js-ctypes 使用。例如:?wmctrl_find_window@@YAKPAD@Z
是 C++ api 函数的“普通 C”符号,称为wmctrl_find_window
.
需要注意的是,此代码依赖于临时能够更改需要聚焦的窗口的标题,以便 Win32 API 可以检查桌面上的所有窗口以找到正确的 Firefox 窗口。
您需要访问特权 Mozilla 平台 API,即:Firefox 插件中的 JavaScript。
在您的特权 JavaScript 代码中:
// get API constants (might already be available)
const {Cc,Ci,Cu} = require("chrome");
// import js-ctypes
var file=null, lib=null, ctypes = {};
Cu.import("resource://gre/modules/ctypes.jsm", ctypes);
var ctypes = ctypes.ctypes;
// build platform specific library path
var filename = ctypes.libraryName("wmctrl"); // automatically adds '.dll'
var comp = "@mozilla.org/file/directory_service;1";
var file = Cc[comp].getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile);
file.append("browser_code"); // or whereever you put your DLL
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", /* plain "C" DLL symbol */
ctypes.stdcall_abi, ctypes.uint32_t, /* return type: uint32 */
ctypes.char.ptr); /* parameter: string */
// wmctrl_window_focus: takes unsigned 32bit (long) "window handle".
var window_focus = lib.declare(
"?wmctrl_window_focus@@YAXK@Z", /* plain "C" DLL symbol */
ctypes.stdcall_abi, ctypes.void_t, /* return type: void */
ctypes.uint32_t); /* parameter: uint32 */
wmctrldll.h
#ifdef WMCTRLDLL_EXPORTS
#define WMCTRLDLL_API __declspec(dllexport)
#else
#define WMCTRLDLL_API __declspec(dllimport)
#endif
WMCTRLDLL_API void wmctrl_window_focus (unsigned long wid);
WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title);
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;
}