Python Window Activation

Viewed 88440

How would I programmatically activate a window in Windows using Python? I'm sending keystrokes to it and at the moment I'm just making sure it's the last application used then sending the keystroke Alt+Tab to switch over to it from the DOS console. Is there a better way (since I've learned by experience that this way is by no means foolproof)?

5 Answers

You can use the win32gui module to do that. First you need to get a valid handle on your window. You can use the win32gui.FindWindow if you know the window class name or the exact title. If not, you can enumerate the windows with the win32gui.EnumWindows and try to find the right one.

Once you have the handle, you can call the win32gui.SetForegroundWindow with the handle. It will activate the window and will be ready for getting your keystrokes.

See an example below. I hope it helps

import win32gui
import re


class WindowMgr:
    """Encapsulates some calls to the winapi for window management"""

    def __init__ (self):
        """Constructor"""
        self._handle = None

    def find_window(self, class_name, window_name=None):
        """find a window by its class_name"""
        self._handle = win32gui.FindWindow(class_name, window_name)

    def _window_enum_callback(self, hwnd, wildcard):
        """Pass to win32gui.EnumWindows() to check all the opened windows"""
        if re.match(wildcard, str(win32gui.GetWindowText(hwnd))) is not None:
            self._handle = hwnd

    def find_window_wildcard(self, wildcard):
        """find a window whose title matches the wildcard regex"""
        self._handle = None
        win32gui.EnumWindows(self._window_enum_callback, wildcard)

    def set_foreground(self):
        """put the window in the foreground"""
        win32gui.SetForegroundWindow(self._handle)


w = WindowMgr()
w.find_window_wildcard(".*Hello.*")
w.set_foreground()
import ctypes, platform

if platform.system() == 'Windows':
    Active_W = ctypes.windll.user32.GetActiveWindow()
    ctypes.windll.user32.SetWindowPos(Active_W,0,0,0,0,0,0x0002|0x0001)

Here we go. you just need to store the value of the active window.

Pip install keyboard. Before you set foreground window, simulate a keyboard to esc that is keyboard.send('esc') You may want to do it three times for either of the following:

  1. Sidebar
  2. Windows key overlay
  3. Task manager which is always on top

Using SetWindowPos or SetForegroundWindow might NOT be enough if the window was minified aka IsIconic! We can use ShowWindow with SW_RESTORE (9):

import ctypes

def activate_window(hwnd):
    user32 = ctypes.windll.user32
    user32.SetForegroundWindow(hwnd)
    if user32.IsIconic(hwnd):
        user32.ShowWindow(hwnd, 9)

Depending on how you identify the desired window there are some ways to get the hwnd aka window handle.

You could loop through all the windows to find the right handle according to the pid via user32.GetWindowThreadProcessId or by window name with user32.GetWindowTextW

To get ProcessIds you could use Windows built-in wmic. There are loads of other nifty things you can do with it. (all attributes: wmic process get /?) (get handle is broken tho) For example:

def get_pids(proc_name):
    out = subprocess.check_output('wmic process where Name="%s" get ProcessId' % proc_name)
    pids = out.decode().strip().split()[1:]
    if not pids:
        raise WindowsError('Could not find pids for process')
    return [int(pid) for pid in pids]
Related