14

タイトルを検索してウィンドウを見つけるプログラムを作成しようとしています。ウィンドウが見つかると、それを前面に移動しようとします。win32guiこれを実現するためにAPIを使用しています。ほとんどの場合、動作させることができますが、タスクマネージャーが前面にあると、何らかの理由で動作しません。次のサンプルコードがあります。

import win32gui, win32con
import re, traceback
from time import sleep

class cWindow:
    def __init__(self):
        self._hwnd = None

    def BringToTop(self):
        win32gui.BringWindowToTop(self._hwnd)

    def SetAsForegroundWindow(self):
        win32gui.SetForegroundWindow(self._hwnd)

    def Maximize(self):
        win32gui.ShowWindow(self._hwnd, win32con.SW_MAXIMIZE)

    def setActWin(self):
        win32gui.SetActiveWindow(self._hwnd)

    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))) != None:
            self._hwnd = hwnd

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


def main():
    sleep(5)
    try:      
        wildcard = ".*Building Operation WorkStation.*"
        cW = cWindow()
        cW.find_window_wildcard(wildcard)
        cW.Maximize()
        cW.BringToTop()
        cW.SetAsForegroundWindow()

    except:
        f = open("log.txt", "w")
        f.write(traceback.format_exc())
        print traceback.format_exc()
main()

これを複数のオンライン ソースからつなぎ合わせました。ほとんどの場合は機能するようですが、タスク マネージャーなどの一部のウィンドウでは、機能することもありますが、残りは失敗します。正常に動作しない場合、アプリケーションのアイコンが黄色に点滅するだけです。私が興味を持っているウィンドウが 100% の時間前景に設定されていることを確認するためにこれを行う適切な方法はありますか? これが関連しているかどうかはわかりませんが、Service Pack 1 を適用した Windows 7 Professional (32 ビット) を使用しています。

4

2 に答える 2

9

私は解決策を見つけました:もしタスクマネージャーなら、それを殺してください。にメソッドを追加しましたcWindow

def kill_task_manager(self):
    # Here I use your method to find a window because of an accent in my french OS,
    # but you should use win32gui.FindWindow(None, 'Task Manager complete name').
    wildcard = 'Gestionnaire des t.+ches de Windows'
    self.find_window_wildcard(wildcard)
    if self._hwnd:
        win32gui.PostMessage(self._hwnd, win32con.WM_CLOSE, 0, 0)  # kill it
        sleep(0.5)  # important to let time for the window to be closed

の直後にこのメソッドを呼び出しcW = cWindow()ます。

もう 1 つのバグ トラップは、次のような例外を防ぐことですSetAsForegroundWindow

error: (0, 'SetForegroundWindow', 'No error message is available')

win32gui 呼び出しの前に Alt キーを送信するだけです:

# Add this import
import win32com.client

# Add this to __ini__
self.shell = win32com.client.Dispatch("WScript.Shell")

# And SetAsForegroundWindow becomes
def SetAsForegroundWindow(self):
    self.shell.SendKeys('%')
    win32gui.SetForegroundWindow(self._hwnd)

最後に、もしよろしければ、比較はしないで!= Noneくださいis not None。もっとpythonic;)

これは完全なコードです:

# coding: utf-8

import re, traceback
import win32gui, win32con, win32com.client
from time import sleep


class cWindow:
    def __init__(self):
        self._hwnd = None
        self.shell = win32com.client.Dispatch("WScript.Shell")

    def BringToTop(self):
        win32gui.BringWindowToTop(self._hwnd)

    def SetAsForegroundWindow(self):
        self.shell.SendKeys('%')
        win32gui.SetForegroundWindow(self._hwnd)

    def Maximize(self):
        win32gui.ShowWindow(self._hwnd, win32con.SW_MAXIMIZE)

    def setActWin(self):
        win32gui.SetActiveWindow(self._hwnd)

    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._hwnd = hwnd

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

    def kill_task_manager(self):
        wildcard = 'Gestionnaire des t.+ches de Windows'
        self.find_window_wildcard(wildcard)
        if self._hwnd:
            win32gui.PostMessage(self._hwnd, win32con.WM_CLOSE, 0, 0)
            sleep(0.5)

def main():
    sleep(5)
    try:
        wildcard = ".*Building Operation WorkStation.*"
        cW = cWindow()
        cW.kill_task_manager()
        cW.find_window_wildcard(wildcard)
        cW.BringToTop()
        cW.Maximize()
        cW.SetAsForegroundWindow()

    except:
        f = open("log.txt", "w")
        f.write(traceback.format_exc())
        print(traceback.format_exc())


if __name__ == '__main__':
    main()

ソース: Python で win32guiとwin32gui.SetActiveWindow()を使用してハンドルでウィンドウを閉じるにはどうすればよいですか?エラー: 指定されたプロシージャが見つかりませんでした

于 2015-05-18T23:10:12.660 に答える