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
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")
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
.
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)
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')
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);
Late answer, but you can use:
import win32gui
hwnd = win32gui.FindWindowEx(0,0,0, "Window Title")
win32gui.SetForegroundWindow(hwnd)