Как прослушивать события щелчка мыши на значке панели задач для запущенного в данный момент приложения в windows с использованием python? - PullRequest
0 голосов
/ 24 января 2020

Я пытаюсь прослушивать события щелчка мыши на значках приложений на панели задач для текущих запущенных приложений в windows с использованием python. В приведенном ниже примере я использую python для запуска приложения inte rnet explorer. После запуска приложения я использую функцию API FindWindow windows, чтобы получить идентификатор окна / дескриптор.

Есть ли способ прослушивания щелчков мыши на значке панели задач inte rnet explorer пользователем с помощью windows API или каким-либо другим способом? Мне нужно напечатать сообщение при нажатии на значок IE на панели задач.

enter image description here

Вот код, с которым я работаю в настоящее время:

from win32gui import GetWindowText, GetForegroundWindow, FindWindow
import win32api, win32gui
import win32con
import sys, os

os.system('"C:\Program Files (x86)\Internet Explorer\iexplore.exe"') #open internet explorer application.. this will make the internet explorer icon appear in the taskbar..

window_id = FindWindow(0, 'Internet Explorer') #find the newly opened IE window's id/handle
print (window_id) 

class test:

    def __init__(self, **kwargs):
        super(test, self).__init__(**kwargs)
        self.oldWndProc = win32gui.SetWindowLong(window_id, win32con.GWL_WNDPROC, self.MyWndProc)
        self.msgdict = {} 
        for name in dir(win32con):
            if name.startswith("WM_"):
                value = getattr(win32con, name)
                self.msgdict[value] = name
        print (self.msgdict) #I can access all the win32 window events using this dictionary..

    #listener to track win32 window events related to the newly opened internet explorer window..
    #how do I track when the internet explorer icon is CLICKED in the task bar??
    def MyWndProc(self, hWnd, msg, wParam, lParam):
        print (self.msgdict.get(msg)) #none of the window events print here..
        return win32gui.CallWindowProc(self.oldWndProc, hWnd, msg, wParam, lParam)

t = test()

Ответы [ 2 ]

1 голос
/ 28 января 2020

Попробуйте использовать UI Automation .

Имя класса окна панели задач: MSTaskListWClass:

enter image description here

И вы также можете увидеть элемент UIA и его BoundingRectangle из inspect.exe:

enter image description here

Сначала вы можете получить событие click на рабочем столе и затем получите значок задачи IUIAutomationElement, затем используйте GetClickablePoint, чтобы определить, есть ли щелчок по элементу.

0 голосов
/ 29 января 2020

Благодаря Дрейку Ву, направившему меня в правильном направлении, я смог использовать python, чтобы получить информацию UI Automation об элементе, по которому щелкают, и его родителе. Используя эту информацию, я могу сказать, что значок приложения на панели задач щелкается, когда ControlType для элемента, который щелкнул, является «ButtonControl», а имя класса его родителя - «MSTaskListWClass». Вы можете выяснить, какое приложение было нажато, посмотрев на идентификатор автоматизации выбранного элемента.

Для этого примера вам нужно установить pia install uiautomation. Мне пришлось добавить несколько дополнительных функций / методов в файл uiautomation.py, потому что в нем отсутствовали необходимые функции.

Вот методы, которые я добавил в файл uiautomation.py, чтобы сделать его более полезным для этого примера (см., Где он говорит НОВЫЙ КОД ЗДЕСЬ):

def ControlFromPoint(x: int, y: int) -> Control:
    """
    Call IUIAutomation ElementFromPoint x,y. May return None if mouse is over cmd's title bar icon.
    Return `Control` subclass or None.
    """
    element = _AutomationClient.instance().IUIAutomation.ElementFromPoint(ctypes.wintypes.POINT(x, y))
    return Control.CreateControlFromElement(element)

#NEW CODE HERE
def GetElementFromPoint(x: int, y: int) -> Control: #gets the element from a point (x, y)
    element = _AutomationClient.instance().IUIAutomation.ElementFromPoint(ctypes.wintypes.POINT(x, y))
    return element

#NEW CODE HERE
def GetParentElement(element): #gets the parent of an element input
    parent_element = _AutomationClient.instance().ViewWalker.GetParentElement(element)
    return parent_element

#NEW CODE HERE
def GetElementInfo(element): #gets the property information about an element
    element_info = Control.CreateControlFromElement(element)
    return element_info

Затем я использовал эти Недавно добавленные методы автоматизации в главном примере ниже:

import sys, os
from pynput import mouse
from pynput.mouse import Controller
from pynput.mouse import Listener
import uiautomation
from uiautomation import GetElementFromPoint, GetParentElement, GetElementInfo #these are newly added methods to make this example work

mouse2 = mouse.Controller()

class test:

    last_mouse_pos_x = ''
    last_mouse_pos_y = ''

    def __init__(self, **kwargs):
        super(test, self).__init__(**kwargs)
        self.mouse_listener() #start mouse listener

    def mouse_listener(self):
        global element_clicked
        while True:
            if mouse2.position[0] != test.last_mouse_pos_x or mouse2.position[1] != test.last_mouse_pos_y:
                element_clicked = uiautomation.GetElementFromPoint(mouse2.position[0], mouse2.position[1]) #returns the element that you clicked (this has to run here or it errors)
                test.last_mouse_pos_x = mouse2.position[0]
                test.last_mouse_pos_y = mouse2.position[1]

    def on_click(x, y, button, pressed):
        if pressed:
            try:
                element_clicked_info = GetElementInfo(element_clicked) #returns info about the element you clicked
                parent_of_element_clicked = uiautomation.GetParentElement(element_clicked) #returns the parent of the element that you clicked
                parent_of_element_clicked_info = GetElementInfo(parent_of_element_clicked) #returns info about the parent of the element you clicked
                #print info about the element you clicked and its parent
                print ("ELEMENT CLICKED INFO: " + str(element_clicked_info))
                print ("PARENT ELEMENT INFO: " + str(parent_of_element_clicked_info)) 
            except:
                pass #skip over any errors

            #ANALYSIS: If ControlType of element clicked = 'ButtonControl' AND class name of its parent = 'MSTaskListWClass', then an app icon in the taskbar was clicked!

    listener = mouse.Listener(on_click=on_click)
    listener.start()

t = test()
...