Well you can now do the same with pywinauto :-)
I had tried to get this right before and hadn't succeeded - but I managed it today. HwndWrapper.SetFocus will now make the window the foreground window - even if it is not the current foreground window.
This was easy enough really - and I had thought that I had tried this already - but obviously hadn't :-(
Here is the new SetFocus method...
"""Set the focus to this control
Activate the window if necessary"""
# find the current foreground window
cur_foreground = win32functions.GetForegroundWindow()
# if it is already foreground then just return
if self.handle != cur_foreground:
# get the thread of the window that is in the foreground
cur_fore_thread = win32functions.GetWindowThreadProcessId(
# get the thread of the window that we want to be in the foreground
control_thread = win32functions.GetWindowThreadProcessId(self, 0)
# if a different thread owns the active window
if cur_fore_thread != control_thread:
# Attach the two threads and set the foreground window
cur_fore_thread, control_thread, True)
# detach the thread again
cur_fore_thread, control_thread, False)
else: # same threads - just set the foreground window
# make sure that we are idle before returning
# only sleep if we had to change something!
And here is a short bit of code you can test it with
from pywinauto.application import Application
app = Application.start("Notepad.exe")
for i in range(4):
If you run that code and work with other windows - then the Notepad Font dialog will popup (annoyingly :-) ) every 2 seconds.
All is left now is to add a call to this method in those other methods that REQUIRE the window to have focus (TypeKeys() for sure, maybe the ...Input() methods - but they probably require a WindowFromPoint/RealChildWindowFromPoint/ChildWindowFromPoint call first to ensure it's necessary).
(all happy with myself for getting that off the todo list - except it wasn't on the todo list :-D )