如果没有标题,如何使窗口成为焦点? [英] How to bring a window into focus if it does not have a title?

查看:30
本文介绍了如果没有标题,如何使窗口成为焦点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have an app that is built with openframeworks. When started, it first opens a console window that does some work (and stays open) and then starts two more child processes that each open a window in fullscreen, one on each monitor. According to the guy that is building the app, it is impossible to give those two windows titles.

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

My job is to build a script that:

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

我想重用我的一个旧 python 脚本,它正是这样做的,并对其进行了修改以符合要求.

I want to reuse an old python script of mine that did exactly this and altered it to fit the bill.

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 电影程序这样的随机程序(或者至少将它们带到前台,这很奇怪因为它们不应该运行).

Now the checking for crashing and restarting works just fine. But since the windows have no title, the best I've come up with so far is to check for windows with no name, which apparently opens random programms like the Windows 10 movie programm (or at least brings them to the foreground which is weird because they should not be running).

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

Is there a better way to bring a window into focus without knowing its name? One thought of mine was to get the parent process and then access the children from there and bring them into focus somehow, but I've not been able to figure out how.

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

If there are better ways to achieve what I want than using python, I would also be glad for any pointers in that direction.

推荐答案

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

One thought of mine was to get the parent process and then access the children from there and bring them into focus somehow, but I've not been able to figure out how."

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

I've been through the very similar issue, I wanted to find a child proccess with random title name, I only had the name of the executable. Here is what I've done.

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).

So, this is a function that will call win32gui.EnumWindows, which handles all top-level windows. Those windows will be appended to the window_list, letting us know all the ID's and window names... In the loop, we will iterate over the list and match the PID you want to bring to focus... You can comment both print(i) if you want.

这里是文档:

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

这篇关于如果没有标题,如何使窗口成为焦点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆