I have written a program that will change the foreground window to 85% of the monitor\'s dimensions and to run successfully the foreground window needs to remain the same.
Although pythonw
does run the script in the background without opening a command prompt window, your batch file does (even if this window is minimized). So you'll have to find the window that was active before your batch file was executed.
We use the EnumWindows function to iterate over our normal (i.e. visible and with a title) windows. The previous window is the second one in the enumeration. However, if you run the python script from a batch file, the command prompt window (as explained above) will be the previous window, so the one we're looking for is the third one in the enumeration.
#! python
import win32api
import win32gui
import win32con
monitors = win32api.EnumDisplayMonitors()
monitorsDict = {}
window_counter = [0]
def enumWindowsProc(hwnd, param):
if win32gui.IsWindowVisible(hwnd) and win32gui.GetWindowTextLength(hwnd) > 0:
window_counter[0] += 1
print(win32gui.GetWindowText(hwnd))
if window_counter[0] == 3:
window_counter[0] = hwnd
return False
return True
try:
win32gui.EnumWindows(enumWindowsProc,window_counter)
except:
pass
hwnd = window_counter[0]
currentWindowDimensions = win32gui.GetWindowRect(hwnd)
monitorInFocus = str(win32api.MonitorFromWindow(hwnd))
for i in range(len(monitors)):
monitorsDict[str(monitors[i][0])] = monitors[i][2]
maxWidth = (monitorsDict[monitorInFocus][2]-monitorsDict[monitorInFocus][0]) * .85
maxHeight = (monitorsDict[monitorInFocus][3]-monitorsDict[monitorInFocus][1]) * .85
x = int(currentWindowDimensions[0])
y = int(currentWindowDimensions[1])
newWidth = int(maxWidth + x)
newHeight = int(maxHeight + y)
newDimensions = (x, y, newWidth, newHeight)
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, x, y, newWidth, newHeight, 0)
EnumWindows
calls the callback function pass to it until this returns False
. Unfortunately there's a bug in the win32 implementation: when the callback returns False
, EnumWindows
return 0
and this 0
is mistakenly considered an error and python will raise a run time error. A workaround is ignoring this error (as shown here) or just never return False
and thus enumerate the windows list till the very end although we've already found our window.
Instead of using a batch file, there's a more elegant way to invoke your script without creating an extra batch file: in the shortcut on your desktop, you can just insert the one line C:\path\to\pythonw\executable\pythonw.exe C:\path\to\pyw\script\WindowSizing.pyw
as the target. But remember, in this case we need to look for window number 2 instead of 3, so it'll be C:\path\to\pythonw\executable\pythonw.exe C:\path\to\pyw\script\WindowSizing.pyw
.
I tested both approaches (batch file and direct shortcut target) on Windows 7 and both work fine, invocated by short cut key or by clicking on the icon on the desktop.