0

I was having trouble focusing window of another process id.

I had issue when it was minimized, i fixed that by testing IsIconic then doing ShowWindow. But now if the process is not the foreground process it doesn't show.

SetForeground documentation says:

Any ideas on how to bring process to foreground?

I saw this method:

EnumWindows((WNDENUMPROC)topenumfunc, processid) ;

Used here: http://www.mombu.com/microsoft/windows-programmer-win32/t-bring-process-to-foreground-page2-1656417.html

However this enumerates ALL windows and does callback testing if current windows pid is equal to that of processid which was supplied to the EnumWindows func. I just want to run on a single window.

This is my FocusWindow function:

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;
    }
}
Noitidart
  • 35,443
  • 37
  • 154
  • 323
  • Did you read the remarks of the `SetForegroundWindow` function? – paa Aug 10 '14 at 10:01
  • Yes and Im trying to get around that. Basically I'm trying to simulate a `Alt+Tab` to a window. I even found the [`SwitchToThisWindow`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms633553%28v=vs.85%29.aspx) function but that is so wonky, check it out here, I have some notes in the readme on its wonkiness: [GitHubGIST :: Noitidart / _ff-addon-snippet-SwitchToThisWindow](https://gist.github.com/Noitidart/b7a2dc27014276a3ca2e) – Noitidart Aug 10 '14 at 10:29
  • Solution to this answer I found myself is here - http://stackoverflow.com/a/32038880/1828637 – Noitidart Mar 23 '16 at 03:20

1 Answers1

0

Assuming there is a parent process and several children processes, then its one child process must execute the AllowSetForegroundWindow function with the parent process id as a parameter.

Then the parent process can successfully call SetForegroundWindow.

paa
  • 5,048
  • 1
  • 18
  • 22
  • Thanks man I checked this out the other day, it won't work. Say I'm in Firefox Profile 1 and want to focus window of Profile 2. So from Profile 1 I call `AllowSetForegroundWindow` with the process id of Profile 2. Now Profile 2 can succesfully call `SetForegroundWindow`, but my add-on is running out of Profile 1 so I can't run any code in Profile 2. – Noitidart Aug 10 '14 at 20:12
  • What prevents you from installing the extension on every profile? After all the user already installed it once. – paa Aug 11 '14 at 09:09
  • It's up to the user to install or not. They may choose not to install on some profiles. I think I got what the issue was. To test the `SetForegroundWindow` call i was doing setimeout and then having the scratchapad i was running code from set froeground indow to itself after 5sec. In that 5sec I would go focus another process id (like notepad or something). I think the issue is that the process calling `SetForegroundWindow` must be the on top process. – Noitidart Aug 11 '14 at 16:23
  • Figured out the problem paa. When I was testing it. I would do a settimeout for 5 sec. In that 5 sec i would go focus a notepad window. And then after 5 sec it would setforeground back to the firefox window. I didn't understand that the one calling setforegroundwindow should be in the foreground properly. – Noitidart Aug 14 '14 at 14:03