获取windows程序界面信息的方法: spy++ & pywin32(api) Acemyzoe

获取windows程序界面信息的方法

  1. 工具:spy++(vs) 模块:win32-api(c++/c#) pywin32(python)
  2. 使用SPY.exe/SPY++.exe定位到Window程序界面窗口(重要的是类CLASS和窗口的标题CAPTION信息)

eg : 获取计算器窗口信息

import win32file, win32api, win32con,win32gui
import os,sys

def find_idxSubHandle(pHandle, winClass, index=0):
    """
    已知子窗口的窗体类名
    寻找第index号个同类型的兄弟窗口
    """
    assert type(index) == int and index >= 0
    handle = win32gui.FindWindowEx(pHandle, 0, winClass, None)
    while index > 0:
        handle = win32gui.FindWindowEx(pHandle, handle, winClass, None)
        index -= 1
    return handle
  
def find_subHandle(pHandle, winClassList):
    """
    递归寻找子窗口的句柄
    pHandle是祖父窗口的句柄
    winClassList是各个子窗口的class列表,父辈的list-index小于子辈
    """
    assert type(winClassList) == list
    if len(winClassList) == 1:
        return find_idxSubHandle(pHandle, winClassList[0][0], winClassList[0][1])
    else:
        pHandle = find_idxSubHandle(pHandle, winClassList[0][0], winClassList[0][1])
        return find_subHandle(pHandle, winClassList[1:])

def getdata(handle):
    return win32gui.GetWindowText(handle)

def demo():
    parenthandle = win32gui.FindWindow("CalcFrame", "计算器")
    data=[]
    for i in range(4):
        handle = find_subHandle(parenthandle, [("CalcFrame", 0), ("#32770", 0), ("Static", i)])
        #print("%x" % (handle))
        data.append(getdata(handle))
        #print(i,getdata(handle))
    #print('计算器数据:',data)
    #input()
    #os.system('pause')
    return data

if __name__=='__main__':
    while True:
        demo()

More fun

more examples

import json

import win32api
import win32con
import win32gui

#获取所有打开的窗口句柄和窗口名
hwnd_title = dict()
def get_all_hwnd(hwnd,mouse):
    if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
        hwnd_title.update({hwnd:win32gui.GetWindowText(hwnd)})
win32gui.EnumWindows(get_all_hwnd, 0)
for k in list(hwnd_title.keys()):
    if not hwnd_title[k]:
        del hwnd_title[k]
print(json.dumps(hwnd_title,indent=4,ensure_ascii=False))

classname = None
titlename = "计算器"
#获取句柄
hwnd = win32gui.FindWindow(classname, titlename)
#获取窗口左上角和右下角坐标
left, top, right, bottom = win32gui.GetWindowRect(hwnd)
#鼠标定位到(30,50)
win32api.SetCursorPos([30,150])
#执行左单键击,若需要双击则延时几毫秒再点击一次即可
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP | win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
#右键单击
win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP | win32con.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)
#回车
win32api.keybd_event(13,0,0,0)
win32api.keybd_event(13,0,win32con.KEYEVENTF_KEYUP,0)
#关闭窗口
win32gui.PostMessage(win32gui.FindWindow(classname, titlename), win32con.WM_CLOSE, 0, 0)