Firefox addon Firefox引导扩展:获取浏览器窗口的本机HWND句柄
我有一个外部应用程序,我希望它在浏览器窗口顶部显示一些信息。我的引导扩展需要将浏览器窗口句柄(本机HWND)以及其他一些有关窗口的有用信息传递给我的应用程序。我能够完成它们之间的通信,唯一缺少的是获取Firefox窗口的本地HWND的方法 我读了很多关于它的书,虽然我相信这是可能的,但我找不到一个有效的解决方案。以下是我迄今为止所尝试的: 这个应该给我Firefox addon Firefox引导扩展:获取浏览器窗口的本机HWND句柄,firefox-addon,xul,xpcom,jsctypes,Firefox Addon,Xul,Xpcom,Jsctypes,我有一个外部应用程序,我希望它在浏览器窗口顶部显示一些信息。我的引导扩展需要将浏览器窗口句柄(本机HWND)以及其他一些有关窗口的有用信息传递给我的应用程序。我能够完成它们之间的通信,唯一缺少的是获取Firefox窗口的本地HWND的方法 我读了很多关于它的书,虽然我相信这是可能的,但我找不到一个有效的解决方案。以下是我迄今为止所尝试的: 这个应该给我nsIBaseWindow,这样我就可以得到nsIBaseWindow.nativeHandle或nsIBaseWindow.ParentNati
nsIBaseWindow
,这样我就可以得到nsIBaseWindow.nativeHandle
或nsIBaseWindow.ParentNativeWindow
,但没有成功:
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);
上面的代码在论坛上广泛传播,但我无法让它为我工作
另一个似乎不太准确,因为它根据窗口的类和标题获取HWND,这可能导致错误的结果:
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);
任何帮助都将不胜感激。
窗口必须是根窗口(即ChromeWindow
的实例)
下面的代码应该可以工作
var win=Cc[“@mozilla.org/appshell/window mediator;1”].getService(Ci.nsIWindowMediator.getMostRecentWindow(“导航器:浏览器”);
var basewindow=win.QueryInterface(Ci.nsInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
树主先生
.QueryInterface(Ci.NSInterfaceRequestor)
.nsIBaseWindow;
var nativehandle=basewindow.nativehandle;
问题是我在注册的xul窗口中从主题
参数查询错误的界面。我需要得到一个nsIDOMWindow
而不是nsIXULWindow
,这样我问题中提到的第一个代码就可以工作了。因此,现在我正在使用@Noit建议的一些代码执行以下操作:
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;
}
而且它有效
非常感谢您的帮助。我也遇到了这个问题,可能会很好:
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*/
用户“paa”中的代码在Firefox版本69之前一直有效。
如果在Firefox 70中执行,您将得到一个异常:
TypeError: win.QueryInterface is not a function
这很奇怪,因为变量win
在Firefox 69和70中具有相同的内容
当我执行alert(win)
时,我在两种浏览器中都得到:“[object ChromeWindow]”
和alert(win.document.title)
在两种浏览器中正确显示文档的标题
我下载了两个Firefox版本的源代码来比较它们,并可能找到原因。但是Firefox的源代码非常庞大(2GB),几乎完全没有评论。我发现我用这种方法是在浪费时间
要理解Firefox的源代码是非常困难的,Firefox运行在多个相互通信的进程上。变量<代码> Win >对应于C++类<代码> MZIDOMWOWOVER代理> /COD>或<代码> NSHCROMEOUTWORKOVEXORGODS。但这些似乎只是其他类的包装类。最后,我放弃了理解Firefox源代码的尝试
但经过几个小时的反复尝试,我终于找到了解决办法
更简单的是:
var baseWindow = win.docShell
.treeOwner
.nsIBaseWindow;
它可以在Firefox70到79(目前是最新版本)上运行。但是,这段新代码不在Firefox版本上运行,我需要从xul窗口内注册ChromeWindow
事件观察程序,以便测试您的解决方案。我有事件处理程序:observe:function(subject,topic,data){…}
,这是我需要获取句柄的地方,但我只知道如何从那里获取nsIDOMWindow
,而不是创建的ChromeWindow
,注册的xul窗口
通知的主题是您正在查找的窗口。我试图使用它,但它是一个nsi支持的
界面。当我试图从中获取basewindow
时,我得到一个错误:[nsinterfacerequestor.getInterface]“nsresult:”0x80004002(NS_NOINTERFACE)“
要进行测试,您可以将其代码复制粘贴到草稿行中,并将环境设置为“浏览器”。效果很好。@Kekas我想当观察者收到xulwindowregistered
主题通知时,窗口对象的初始化没有完成。也许你应该等到load
事件被触发。非常感谢你分享这段代码,它将帮助人们再次感谢你分享这段代码,我遇到了一个问题,当时我正在设置一个窗口的标题,然后做FindWindow
,但是FindWindow没有找到它,因为它在更改窗口标题后运行得太快了。然后我想起了这个主题,现在甚至不需要FindWindow
超级男人再次感谢!!这就是人们应该始终共享解决方案的原因!:)这段代码在Firefox70上不再有效。请看我的答案。它不是很可靠,因为它使用窗口的标题,并且一些发行版有不同的名称。更不用说标题可能会在过程中更改,或者多个窗口具有相同的标题,最终可能会得到错误的句柄。
TypeError: win.docShell is undefined