How to run python program in background to keep active window the same

前端 未结 1 1996
我寻月下人不归
我寻月下人不归 2021-01-27 00:47

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.

相关标签:
1条回答
  • 2021-01-27 01:15

    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.

    0 讨论(0)
提交回复
热议问题