xul:多个监视器上的面板位置

时间:2012-04-09 07:56:09

标签: javascript firefox xul

我的firefox扩展程序上有一个xul:面板。我给出了根据screen.width和screen.height显示的位置。当我有多个显示器并且我在第一个显示器上启动浏览器时出现我的问题,它出现在第二个显示器上,并且xul:面板根据第二个屏幕上的第一个屏幕的分辨率绘制。是否有根据第二个屏幕的分辨率绘制的解决方案?

1 个答案:

答案 0 :(得分:2)

背景:

当我开发基于XULRunner的mutli-monitor应用程序工作时,我发现你无法预测窗口管理器在首次启动主应用程序/浏览器窗口后将窗口放到何处。< / p>

XULRunner确实正确地给了我:

  • 完整的多显示器显示的几何(宽度,高度)
  • 多显示器显示屏上给定窗口的窗口位置
  • 给定窗口的窗口状态(MAXIMIZED,MINIMIZED,都没有)
  • 能够(取消)最大化窗口

当我指定一组将窗口放在特定监视器上的窗口坐标时(而不是窗口管理器将新窗口置于任何地方),它不能正确地考虑多监视器几何体。

这让我完成了以下任务:

      
  • 相对于多显示器显示屏定位窗口,以及
    (因为移动窗口有时会失去窗口焦点)
  •   
  • 关注窗口。

我能够在js-ctypes加载/使用的外部DLL的帮助下实现这两者。


Win32示例:

这里是将外部DLL绑定到JavaScript的基础知识。这个例子只涵盖了Win32,但我也为Linux和MacOSX做了这个(与Win32相比,它们更容易和更难)。

共有3个部分:

      
  1. 加载/绑定Win32 API的特权JavaScript代码
  2.   
  3. 外部DLL的CPP头文件
  4.   
  5. 外部DLL的CPP源文件
  6. 我使用后两个文件构建一个简单的GUI DLL项目&amp;编译wmctrl.dll,具体取决于msvcr100.dll,并使用Dependency Walker查找&#34;普通C&#34; DLL导出的符号供js-ctypes使用。

    我还围绕API构建了一个JavaScript库,允许操作,跟踪和扩展。在应用程序的多次运行中保留多个窗口的窗口状态/几何,但这与这个简单的示例并不相关。

    在特权JavaScript代码中:

    // get js-ctypes, you do this part a bit differently from browser chrome
    const {Cc,Ci,Cu} = require("chrome"); 
    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");
    var comp = "@mozilla.org/file/directory_service;1";
    var file = Cc[comp].getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile);
    file.append("browser_code");
    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);
    
    // wmctrl_window_move: takes unsigned 32bit (long) "window handle", 
    // and two (x & y) signed 32bit ints. 
    var window_move = lib.declare("?wmctrl_window_move@@YAXKHH@Z", 
        ctypes.stdcall_abi, ctypes.void_t,
        ctypes.uint32_t, ctypes.int32_t, ctypes.int32_t);
    

    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 void wmctrl_window_move (unsigned long wid, int x, int y);
    WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title);
    

    wmctrldll.cpp

    #include "stdafx.h"
    #include "wmctrldll.h"
    
    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;
    }
    
    WMCTRLDLL_API void wmctrl_window_move(unsigned long wid, int x, int y) {
      UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE;
    
      SetForegroundWindow((HWND) wid);
      SetWindowPos((HWND) wid, HWND_NOTOPMOST, x, y, NULL, NULL, flags);
    }