4

他のプログラムよりも集中する必要がある Firefox 拡張機能を開発しています。window.focus() は、他の Firefox ウィンドウでのみ機能します。これは可能ですか?

4

1 に答える 1

0

これは、私がここで回答した別の質問に似ています: xul:panel position on multiple monitor

js-ctypes によってロード/使用される外部 DLL の助けを借りて、あなたが望むものを達成することができました。OS レベルのウィンドウ フォーカスを操作するには、次の 2 つのことを実行できる必要があります。

  • 問題の Firefox ウィンドウを見つけますfind_window(以下の JavaScript 関数)。
  • ウィンドウにフォーカスします(window_focus以下の関数)。

ウィンドウ ハンドルを見つける最も簡単な方法は、ウィンドウ タイトルを他のウィンドウ タイトルと衝突しない予測可能なもの (たとえば、MD5 の合計"your-app"+(new Date())) に変更し、そのウィンドウを探しているすべての OS レベルのウィンドウを列挙することであることがわかりました。タイトル ( find_window)。

ウィンドウ ハンドルを取得したら、window_focus(以下で定義) を呼び出して OS レベルのウィンドウにフォーカスすることができます。


Win32 の例:

外部 DLL を JavaScript にバインドするための基本は次のとおりです。この例は Win32 のみを対象としていますが、同じプロセスがそれぞれに適用されます。

3 つの部分があります。

  • プラットフォーム固有の (つまり、Win32) API をロード/バインドするための特権 JavaScript コード
  • 外部 DLL の CPP ヘッダー ファイル
  • 外部 DLL の CPP ソース ファイル

msvcr100.dllに応じて、後の2つのファイルとコンパイルされたwmctrl.dllを使用してVS2010で単純なGUI DLLプロジェクトを構築し、依存関係ウォーカーを使用して、js-ctypesで使用するためにDLLによってエクスポートされた「プレーンC」シンボルを見つけました。

特権 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 についても、それほど問題なく実行できました。

于 2012-12-15T12:56:47.913 に答える