【问题标题】:js-ctypes trouble with focusing windowjs-ctypes 聚焦窗口问题
【发布时间】:2014-08-10 07:28:48
【问题描述】:

我无法聚焦另一个进程 ID 的窗口。

当它被最小化时我遇到了问题,我通过测试IsIconic 然后执行ShowWindow 解决了这个问题。但是现在如果进程不是前台进程就不会显示了。

SetForeground 文档说:

关于如何将流程带到前台有什么想法吗?

我看到了这个方法:

EnumWindows((WNDENUMPROC)topenumfunc, processid) ;

在这里使用: http://www.mombu.com/microsoft/windows-programmer-win32/t-bring-process-to-foreground-page2-1656417.html

但是,如果当前窗口 pid 等于提供给 EnumWindows 函数的 processid 的 pid,这会枚举所有窗口并进行回调测试。我只想在单个窗口上运行。

这是我的FocusWindow 函数:

Cu.import('resource://gre/modules/ctypes.jsm');
var user32 = ctypes.open('user32.dll');

/* http://msdn.microsoft.com/en-us/library/ms633539%28v=vs.85%29.aspx
* BOOL WINAPI SetForegroundWindow(
* __in HWND hWnd
* );
*/
var SetForegroundWindow = user32.declare('SetForegroundWindow', ctypes.winapi_abi, ctypes.bool,
    ctypes.int32_t
);

/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633522%28v=vs.85%29.aspx
* DWORD WINAPI GetWindowThreadProcessId(
* __in_ HWND hWnd,
* __out_opt_ LPDWORD lpdwProcessId
* );
*/
var GetWindowThreadProcessId = user32.declare('GetWindowThreadProcessId', ctypes.winapi_abi, ctypes.unsigned_long, //DWORD
    ctypes.int32_t, //HWND
    ctypes.unsigned_long.ptr //LPDWORD
);

/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633507%28v=vs.85%29.aspx
* BOOL WINAPI IsIconic(
* __in HWND hWnd
* );
*/
var IsIconic = user32.declare('IsIconic', ctypes.winapi_abi, ctypes.bool, // BOOL
    ctypes.int32_t // HWND
);

/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633507%28v=vs.85%29.aspx
* BOOL WINAPI ShowWindow(
* __in HWND hWnd
* __in INT nCmdShow
* );
*/
var ShowWindow = user32.declare('ShowWindow', ctypes.winapi_abi, ctypes.bool, // BOOL
    ctypes.int32_t, // HWND
    ctypes.int // INT
);
var SW_RESTORE = 9;

function FocusWindow(hwnd) {
    if (IsIconic(hwnd)) {
        console.warn('its minimized so un-minimize it');
        //its minimized so unminimize it
        var rez = ShowWindow(hwnd, SW_RESTORE);
        if (!rez) {
            throw new Error('Failed to un-minimize window');
        }
    }
    var rez = SetForegroundWindow(hwnd);
    if (!rez) {
        console.log('could not set to foreground window for a reason other than minimized, maybe process is not foreground, lets try that now');
        var cPid =  ctypes.cast(ctypes.voidptr_t(0), ctypes.unsigned_long);
        var rez = GetWindowThreadProcessId(hwnd, cPid.address());
        if (!rez) {
            throw new Error('Failed to get PID');
        } else {
            console.log('cPid=', cPid, uneval(cPid), cPid.toString());
            console.log('trying to set pid to foreground process');
            return false;
        }
    } else {
        return rez;
    }
}

【问题讨论】:

标签: firefox-addon jsctypes


【解决方案1】:

假设有一个父进程和几个子进程,那么它的一个子进程必须以父进程id为参数执行AllowSetForegroundWindow函数。

那么父进程就可以成功调用SetForegroundWindow了。

【讨论】:

  • 谢谢,前几天我检查了这个,它不起作用。假设我在 Firefox 配置文件 1 中,并且想要关注配置文件 2 的窗口。所以从配置文件 1 我用配置文件 2 的进程 ID 调用 AllowSetForegroundWindow。现在配置文件 2 可以成功调用 SetForegroundWindow,但我的附加组件是Profile 1 用完了,所以我无法在 Profile 2 中运行任何代码。
  • 是什么阻止您在每个配置文件上安装扩展程序?毕竟用户已经安装了一次。
  • 安装与否由用户决定。他们可能会选择不在某些配置文件上安装。我想我明白了问题所在。为了测试SetForegroundWindow 调用,我正在执行setimeout,然后让scratchapad 在5 秒后从set froeground indow 运行代码。在那 5 秒内,我会关注另一个进程 ID(如记事本或其他东西)。我认为问题在于调用SetForegroundWindow 的进程必须是顶层进程。
  • 解决了问题 paa。当我测试它时。我会设置一个 5 秒的超时时间。在那 5 秒内,我会关注一个记事本窗口。然后在 5 秒后它会设置前景回到 Firefox 窗口。我不明白调用 setforegroundwindow 的那个应该正确地在前台。
猜你喜欢
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
相关资源
最近更新 更多