How to find window with wildcard in Python and win32gui

When finding window by the title, sometimes we only know part of the title, we want to find any window with the title contains a substring. The native win32 API FindWindow didn't support it. But we can do it in another way in Python.

The idea is to collect all window titles and search a substring in them. Its very easy to do it in dynamic language like Python.

Here is the code

import sys
from ctypes import *
import win32service
import win32serviceutil
import win32api
import win32event
import win32evtlogutil
import os
import win32con
from win32con import SWP_FRAMECHANGED 
from win32con import SWP_NOMOVE 
from win32con import SWP_NOSIZE 
from win32con import SWP_NOZORDER
from win32con import SW_HIDE
from win32con import SW_FORCEMINIMIZE
from win32con import SW_SHOWNORMAL
from win32con import GW_OWNER 
from win32con import GWL_STYLE 
from win32con import GWL_EXSTYLE 
from win32con import WM_CLOSE 
from win32con import WS_CAPTION 
from win32con import WS_EX_APPWINDOW 
from win32con import WS_EX_CONTROLPARENT
from win32con import WS_EX_TOOLWINDOW
from win32con import WS_EX_WINDOWEDGE
from win32con import WS_EX_LAYERED 
from win32con import LWA_ALPHA
import win32gui
import winxpgui
EnumWindows = windll.user32.EnumWindows
EnumWindowsProc = WINFUNCTYPE(c_bool, c_int, POINTER(c_int))
GetWindowText = windll.user32.GetWindowTextW
GetWindowTextLength = windll.user32.GetWindowTextLengthW
IsWindowVisible = windll.user32.IsWindowVisible
GetClassName = windll.user32.GetClassNameW
BringWindowToTop = windll.user32.BringWindowToTop
GetForegroundWindow = windll.user32.GetForegroundWindow
titles = []
def foreach_window(hwnd, lParam):
    if IsWindowVisible(hwnd):
        length = GetWindowTextLength(hwnd)
        classname = create_unicode_buffer(100 + 1)
        GetClassName(hwnd, classname, 100 + 1)
        buff = create_unicode_buffer(length + 1)
        GetWindowText(hwnd, buff, length + 1)
        titles.append((hwnd, buff.value.encode, classname.value, windll.user32.IsIconic(hwnd)))
    return True
EnumWindows(EnumWindowsProc(foreach_window), 0)
def refresh_wins():
    del titles[:]
    EnumWindows(EnumWindowsProc(foreach_window), 0)
    return titles
def find_window(title):
    newest_titles = refresh_wins()
    for item in newest_titles:
        if title in item[1]:
            return item[0]
    return False
# test
if find_window("findwindow-"):
    print ("found")
    print ("not found")

If I have a window with title "Administrator: cmd - python", I can locate the window with any substring of the title.

The code is very easy to understand, the callback function foreach_window and EnumWindows will collect all visible windows, and whenever we try to search for windows we should refresh the array that store all the windows.