Firefox bootstrapped extension: Get native HWND handle of the browser window

被刻印的时光 ゝ 提交于 2020-01-03 03:20:29

问题


I have an external application and I want it to display some information on top of the browser window. My bootstrapped extension needs to pass the browser window handle (native HWND) to my application, along with some other useful information about the window. I'm able to do the communication between them, the only thing that is missing is a way to get the native HWND of the Firefox window.

I read a lot about it and although I belive it's possible, I couldn't find a working solution. Here's what I've tried so far:

This one should give me nsIBaseWindow, so I could get nsIBaseWindow.nativeHandle or nsIBaseWindow.ParentNativeWindow, but no success:

var window = SomeDOMWindow; // Informative
var baseWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                        .getInterface(Components.interfaces.nsIWebNavigation)
                        .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
                        .treeOwner
                        .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                        .getInterface(Components.interfaces.nsIXULWindow)
                        .docShell
                        .QueryInterface(Components.interfaces.nsIBaseWindow);

The above code is widely spread on forums, but I couldn't get it to work for me.

The other one does not seem to be much accurate since it gets the HWND based on the window's class and title, which can lead to wrong results:

Components.utils.import("resource://gre/modules/ctypes.jsm");
var lib = ctypes.open("user32.dll");
var fww = lib.declare("FindWindowW", ctypes.winapi_abi,
  ctypes.voidptr_t, ctypes.jschar.ptr, ctypes.jschar.ptr);
var sfw = lib.declare("SetForegroundWindow", ctypes.winapi_abi,
  ctypes.int32_t, ctypes.voidptr_t);
var hwnd = fww("MozillaWindowClass", document.title);
setTimeout(function() {
  sfw(hwnd);
  lib.close();
}, 3000);

Any help would be appreciated.


回答1:


window must be a root one (i.e. an instance of ChromeWindow)

The following code should work

var win = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator).getMostRecentWindow("navigator:browser");
var basewindow = win.QueryInterface(Ci.nsIInterfaceRequestor)
                 .getInterface(Ci.nsIWebNavigation)
                 .QueryInterface(Ci.nsIDocShellTreeItem)
                 .treeOwner
                 .QueryInterface(Ci.nsIInterfaceRequestor)
                 .nsIBaseWindow;
var nativehandle = basewindow.nativeHandle;



回答2:


The problem was that I was querying the wrong interface from the subject param in the xul-window-registered observer. I need to get an nsIDOMWindow instead of an nsIXULWindow so the first code mentioned in my question works. So now I'm doing the following, with some piece of code @Noit suggested:

observe: function(subject, topic, data) {
    var newWindow  = subject.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
    var basewindow = newWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                     .getInterface(Ci.nsIWebNavigation)
                     .QueryInterface(Ci.nsIDocShellTreeItem)
                     .treeOwner
                     .QueryInterface(Ci.nsIInterfaceRequestor)
                     .nsIBaseWindow;
    var nativehandle = basewindow.nativeHandle;
}

And it works!

Thank you very much for your help.




回答3:


I also just came across this, it might be nice:

Cu.import("resource://gre/modules/ctypes.jsm");

/*start getcursorpos*/
var lib = ctypes.open("user32.dll");

/*foreground window stuff*/
var FindWindowA = lib.declare('FindWindowA', ctypes.winapi_abi, ctypes.uint32_t, ctypes.jschar.ptr, ctypes.jschar.ptr)
var GetForegroundWindow = lib.declare('GetForegroundWindow', ctypes.winapi_abi, ctypes.uint32_t)
function doFindWindow() {
    var wm = Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator);
    var title = wm.getMostRecentWindow('navigator:browser').gBrowser.contentDocument.title;
    Cu.reportError('title=' + title)
    var ret = FindWindowA('', title + ' - Mozilla Firefox');
    //var ret = GetForegroundWindow();

    Cu.reportError(ret);
}
/*end foreground window stuff*/


来源:https://stackoverflow.com/questions/21991218/firefox-bootstrapped-extension-get-native-hwnd-handle-of-the-browser-window

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!