【问题标题】:Is it possible to make my firefox extension gain focus over other programs?是否可以让我的 Firefox 扩展程序获得对其他程序的关注?
【发布时间】:2012-11-08 20:06:52
【问题描述】:

我正在开发一个 Firefox 扩展程序,我需要将重点放在其他程序上。 window.focus() 仅适用于其他 Firefox 窗口。这可能吗?

【问题讨论】:

  • 更长的答案是肯定的 :-) 取决于您要付出多少努力,以及要支持多少个平台。

标签: javascript firefox window focus


【解决方案1】:

这类似于我在这里回答的另一个问题:xul:panel position on multiple monitors

借助 js-ctypes 加载/使用的外部 DLL,我能够实现您想要的。为了操纵操作系统级别的窗口焦点,您需要能够做两件事:

  • 找到有问题的 Firefox 窗口(下面的find_window javascript 函数),并且
  • 聚焦窗口(@98​​7654323@ 函数下方)。

我发现找到窗口句柄的最简单方法是将窗口标题更改为不会与其他窗口标题冲突的可预测的内容(例如"your-app"+(new Date()) 的 MD5 总和),然后枚举所有操作系统级别的窗口正在寻找具有该标题的窗口 (find_window)。

一旦你有了一个窗口句柄,你就可以调用window_focus(定义如下)来聚焦操作系统级别的窗口。


Win32 示例:

以下是将外部 DLL 绑定到 JavaScript 的基础知识。此示例仅涵盖 Win32,但相同的过程适用于每个。

有3个部分:

  • 用于加载/绑定平台特定(即 Win32)API 的特权 JavaScript 代码
  • 外部 DLL 的 CPP 头文件
  • 我们的外部 DLL 的 CPP 源文件

我在 VS2010 中用后面的两个文件构建了一个简单的 GUI DLL 项目,并根据 msvcr100.dll 编译了 wmctrl.dll,并使用 Dependency Walker 查找 DLL 导出的“纯 C”符号供 js-使用类型。

在特权 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 做了这个,没有太多困难。

【讨论】:

    猜你喜欢
    • 2018-09-24
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    • 2011-12-14
    • 2019-08-21
    • 1970-01-01
    • 2020-05-21
    • 2018-04-02
    相关资源
    最近更新 更多