【问题标题】:How to bring a window into focus if it does not have a title?如果窗口没有标题,如何使窗口成为焦点?
【发布时间】:2017-11-10 12:13:08
【问题描述】:

我们有一个使用 openframeworks 构建的应用程序。启动时,它首先打开一个控制台窗口,该窗口执行一些工作(并保持打开状态),然后再启动两个子进程,每个子进程都以全屏方式打开一个窗口,每个监视器上都有一个。根据正在构建应用程序的人的说法,不可能给这两个窗口标题。

我的工作是构建一个脚本:

  1. 检查应用是否崩溃并重新打开
  2. 验证窗口是否在前景中,其中一个窗口处于焦点位置,如果不是,则修复它们

我想重用我的一个旧 python 脚本,它正是这样做的,并对其进行了修改以适应账单。

from time import sleep
import subprocess
import psutil
import re
import win32gui
import win32con

client_path = "C:\\path_to_app.exe"
window_name = ""


class WindowMgr:
    """Encapsulates some calls to the winapi for window management"""

    def __init__(self, ):
        """Constructor"""
        self._handle = None

    def find_window(self, class_name, window_name=None):
        """find a window by its class_name"""
        self._handle = win32gui.FindWindow(class_name, window_name)

    def _window_enum_callback(self, hwnd, wildcard):
        '''Pass to win32gui.EnumWindows() to check all the opened windows'''
        if re.match(wildcard, str(win32gui.GetWindowText(hwnd))) is not None:
            self._handle = hwnd

    def find_window_wildcard(self, wildcard):
        self._handle = None
        win32gui.EnumWindows(self._window_enum_callback, wildcard)

    def set_foreground(self):
        """put the window in the foreground"""
        win32gui.SetForegroundWindow(self._handle)

    def maximize(self):
        win32gui.ShowWindow(self._handle, win32con.SW_MAXIMIZE)

    def is_minimized(self):
        return win32gui.IsIconic(self._handle)


def client_crashed():
    for pid in psutil.pids():
        if psutil.Process(pid).name() == "app.exe":
            return False
    return True


if __name__ == "__main__":

    w = WindowMgr()
    w.find_window_wildcard(window_name)
    print("Checking")
    while True:
        if client_crashed() is True:
            print("Reopening app.exe")
            subprocess.Popen([client_path])
        else:
            print("Not crashed")
        if w.is_minimized:
            print("Maximizing")
            w.set_foreground()
            w.maximize()
        else:
            print("Not minimized")

        print("Sleeping for 10")
        sleep(10)

现在检查崩溃和重新启动工作正常。但是由于窗口没有标题,到目前为止我想出的最好的方法是检查没有名称的窗口,这显然会打开像 Windows 10 电影程序这样的随机程序(或者至少将它们带到前台,这很奇怪因为它们不应该运行)。

有没有更好的方法在不知道窗口名称的情况下使窗口成为焦点?我的一个想法是获取父进程,然后从那里访问子进程并以某种方式使它们成为焦点,但我无法弄清楚如何。

如果有比使用 python 更好的方法来实现我想要的,我也会很高兴有任何指向这个方向的指针。

【问题讨论】:

    标签: python python-3.x windows-10 openframeworks win32gui


    【解决方案1】:

    如果你有唯一的窗口类名,你可以试试 GetClassName() https://msdn.microsoft.com/en-us/library/windows/desktop/ms633582(v=vs.85).aspx

    或者获取窗口进程 GetWindowThreadProcessId() 并检查它是否是您的应用程序的实例。见How to get the process name in C++

    【讨论】:

    • 这是您要放入应用程序本身的代码吗?我不确定我会在我的脚本中对此做什么。
    • 不,只是一个 API 示例,如果 getCalssName 没有帮助,您可以使用它来获取进程映像/exe 文件的名称。
    • 也许这个List running processes on 64-bit Windows更像是Python方式。
    • 我在获取进程时没有问题,但我不能以这种方式强制窗口聚焦。我可以通过找到它们的父进程来获取这些进程。
    • 首先尝试最大化()。这是一个类似的帖子Python Window Activation,最后列出了 SetWindowsforeground 工作的条件列表,请参阅备注部分SetForegroundWindow function
    【解决方案2】:

    我的一个想法是获取父进程,然后 从那里接近孩子并以某种方式使他们成为焦点,但是 我一直无法弄清楚如何。”

    我遇到了非常相似的问题,我想找到一个随机标题名称的子进程,我只有可执行文件的名称。这是我所做的。

    import win32gui
    
    
    def windowFocusPassingPID(pid):
        def callback(hwnd, list_to_append):
            list_to_append.append((hwnd, win32gui.GetWindowText(hwnd)))
    
        window_list = []
        win32gui.EnumWindows(callback, window_list)
        for i in window_list:
            print(i)  # if you want to check each item
            if pid == i[0]:
                print(i)  # printing the found item (id, window_title)
                win32gui.ShowWindow(i[0], 5)
                win32gui.SetForegroundWindow(i[0])
                break
    
    # Here we will call the function, providing a valid PID
    windowFocusPassingPID(INSERT_PID_HERE_IT_MUST_BE_AN_INTEGER)
    

    所以,这是一个将调用 win32gui.EnumWindows 的函数,它处理所有顶级窗口。这些窗口将被附加到 window_list 中,让我们知道所有的 ID 和窗口名称...... 在循环中,我们将遍历列表并匹配您想要关注的 PID... 如果你愿意,你可以同时评论 print(i)。

    这是文档:

    http://timgolden.me.uk/pywin32-docs/win32gui__EnumWindows_meth.html

    【讨论】:

      猜你喜欢
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 2011-03-10
      • 2011-01-31
      • 1970-01-01
      • 2020-12-03
      • 2014-02-12
      • 1970-01-01
      相关资源
      最近更新 更多