Windows 7: how to bring a window to the front no matter what other window has focus?

后端 未结 9 1657
走了就别回头了
走了就别回头了 2020-11-28 08:04

I\'m implementing a task-bar replacement, dock-like application-switcher style program. It\'s doing some unique stuff with OpenGL, and with keyboard shortcuts, so the way it

相关标签:
9条回答
  • 2020-11-28 08:37

    I saw some great answers above, but needed extra functionality where window name would be a more flexible parameter. On failure it returns false:

    from win32gui import IsWindowVisible, GetWindowText, EnumWindows,\
    ShowWindow, SetForegroundWindow, SystemParametersInfo
    
    #Sub-Functions
    def window_enum_handler(hwnd, resultList):
        if IsWindowVisible(hwnd) and GetWindowText(hwnd) != '':
            resultList.append((hwnd, GetWindowText(hwnd)))
    
    #Prime-Functions
    def winFocus(partial_window_name):
        SystemParametersInfo(8193, 0, 2 | 1)
        handles=[]
        EnumWindows(window_enum_handler, handles)
        for i in handles:
            if str(partial_window_name).upper() in str(i[1]).upper():
                ShowWindow(i[0], 3)
                SetForegroundWindow(i[0])
                return True
        print(partial_window_name + " was not found")
        return False
    
    winFocus("not existing window")
    winFocus("ChroME")
    
    0 讨论(0)
  • 2020-11-28 08:38

    The documentation for the SetForegroundWindow function explains, that this is actually the intended behaviour; processes shouldn't be able to "steal" the focus. However, it's possible to adjust your code so that it works anyway.

    Have a look at the remark section of LockSetForegroundWindow: it explains

    The system automatically enables calls to SetForegroundWindow if the user presses the ALT key[..]

    You can exploit this behaviour by making your program simulate pressing the Alt key using the SendInput function before calling SetForegroundWindow.

    0 讨论(0)
  • 2020-11-28 08:38

    This is how I got mine working:

    import win32gui
    from win32con import (SW_SHOW, SW_RESTORE)
    
    def get_windows_placement(window_id):
        return win32gui.GetWindowPlacement(window_id)[1]
    
    def set_active_window(window_id):
        if get_windows_placement(window_id) == 2:
            win32gui.ShowWindow(window_id, SW_RESTORE)
        else:
            win32gui.ShowWindow(window_id, SW_SHOW)
        win32gui.SetForegroundWindow(window_id)
        win32gui.SetActiveWindow(window_id)
    
    0 讨论(0)
  • 2020-11-28 08:40

    This answer builds on @nspire and @nergeia above, and wraps in a method to find the window handle (https://www.blog.pythonlibrary.org/2014/10/20/pywin32-how-to-bring-a-window-to-front/) into one convenience function:

    def raise_window(my_window):
    
        import win32con
        import win32gui
    
        def get_window_handle(partial_window_name):
    
            # https://www.blog.pythonlibrary.org/2014/10/20/pywin32-how-to-bring-a-window-to-front/
    
            def window_enumeration_handler(hwnd, windows):
                windows.append((hwnd, win32gui.GetWindowText(hwnd)))
    
            windows = []
            win32gui.EnumWindows(window_enumeration_handler, windows)
    
            for i in windows:
                if partial_window_name.lower() in i[1].lower():
                    return i
                    break
    
            print('window not found!')
            return None
    
        # https://stackoverflow.com/questions/6312627/windows-7-how-to-bring-a-window-to-the-front-no-matter-what-other-window-has-fo
    
        def bring_window_to_foreground(HWND):
            win32gui.ShowWindow(HWND, win32con.SW_RESTORE)
            win32gui.SetWindowPos(HWND, win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)
            win32gui.SetWindowPos(HWND, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)
            win32gui.SetWindowPos(HWND, win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_SHOWWINDOW + win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)
    
        hwnd = get_window_handle(my_window)
    
        if hwnd is not None:
            bring_window_to_foreground(hwnd[0])
    
    
    raise_window('Untitled - notepad')
    
    0 讨论(0)
  • 2020-11-28 08:41

    I've had some code that's been running for years, going all the way back to Windows 95. When double clicking the applications system tray icon I always used Win32 API functions such as BringWindowToTop and SetForegroundWindow to bring my application windows to the foreground. This all stopped working as intended on Windows 7, where my input window would end up behind other windows and the window icon would flash on the status bar. The 'work around' that I came up with was this; and it seems to work on all versions of Windows.

    //-- show the window as you normally would, and bring window to foreground.
    //   for example;
    ::ShowWindow(hWnd,SW_SHOW); 
    ::BringWindowToTop(hWnd);
    ::SetForegroundWindow(hWnd);
    
    //-- on Windows 7, this workaround brings window to top
    ::SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
    ::SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
    ::SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0,SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
    
    0 讨论(0)
  • 2020-11-28 08:44

    Late answer, but you can use:

    import win32gui
    hwnd = win32gui.FindWindowEx(0,0,0, "Window Title")
    win32gui.SetForegroundWindow(hwnd)
    
    0 讨论(0)
提交回复
热议问题