SPY++的使用和Python操作

  • 1、spy++的基本操作
    • 1.1 窗口属性查找
    • 1.2 窗口spy++定位
  • 2、python与spy++
    • Source Code
    • Use
  • 下载 Spy++:文末公众号回复 210127 获取压缩包

1、spy++的基本操作

1.1 窗口属性查找


拖住中间的“寻找工具”放到想要定位的软件上,然后松开

  • 以微信为例,我们会得到“微信”这个窗口的句柄,为“00031510”,注意这个句柄是“十六进制”,即“0x31510”。
  • 点击ok我们会看到更详细的属性信息

1.2 窗口spy++定位

  • 同理拖放到“微信”上,获取到“微信”的界面
  • 点击ok,会直接定位到“微信”
  • 在这里我们会看到一条信息
  • 00031510 “微信” WeChatMainWndForPC
    – 00031510:代表十六进制的窗口句柄
    – 微信:代表窗口标题
    – WeChatMainWndForPC:代表窗口的类名

2、python与spy++

Source Code

#!/usr/bin/python
# -*- coding: utf-8 -*-
# @Time   : 2021/1/27 10:50
# @Author : SandQuantimport collections
from win32 import win32gui
import pyautogui
import sysclass PySpy(object):Window = collections.namedtuple('Window', ['caption', 'class_name', 'hwnd_py', 'hwnd_spy'])def __init__(self):pass@classmethoddef window_attr(cls, hwnd_py):"""显示窗口的属性:param hwnd_py: 窗口句柄(十进制):return: Window"""return cls.Window(caption=win32gui.GetWindowText(hwnd_py),class_name=win32gui.GetClassName(hwnd_py),hwnd_py=hwnd_py,hwnd_spy=hex(hwnd_py),)@classmethoddef show_top_windows(cls):"""列出所有的顶级窗口及属性:return: 全部的顶层窗口及对应属性"""containers = []win32gui.EnumWindows(lambda hwnd, param: param.append(cls.window_attr(hwnd)), containers)return containers@classmethoddef find_top_window(cls, caption) -> list:"""查找窗体:param caption: 窗口标题部分文字:return:"""return [w for w in cls.show_top_windows() if caption in w.caption]@classmethoddef find_sub_windows(cls, hwnd_py=None, class_name=None, caption=None, index=None):"""返回窗体下全部的子窗体,默认主窗体下的窗体:param hwnd_py: 句柄 十进制:param class_name: 窗口类名,返回特定类名:param caption: 窗口标题,返回特定标题:param index: 位置,返回特定位置的窗口:return: 包含属性的全部子窗口"""num = 0handle = 0sub_windows = []while True:# find next handle, return HwndPyhandle = win32gui.FindWindowEx(hwnd_py, handle, class_name, caption)if handle == 0:# no more handlebreak# get handle attributionattr = cls.window_attr(handle)# append to listsub_windows.append(tuple(list(attr) + [num]))num += 1if index is not None:return sub_windows[index]else:return sub_windows@classmethoddef show_all_windows(cls, window=None, handle_list=None, handle_dict=None):"""生成窗口全部对应的关系:param window: 目标父窗口:param handle_list: 默认为[[None]]:param handle_dict: 用于存放对应关系:return: 返回目标窗口下全部子父窗口的字典"""if not handle_list and not handle_dict:handle_list = [[None]]handle_dict = dict()sys.setrecursionlimit(1000000)if window:handle_list[-1][0] = windowhandles = cls.find_sub_windows(handle_list[-1][0][2])else:handles = cls.find_sub_windows()for handle in handles:handle_dict[handle] = window# 这个根节点已经遍历完,删除del handle_list[-1][0]# 如果有叶节点,非空,则加入新的叶节点if handles:handle_list.append(handles)# 删除已被清空的根handle_list = [HandleGroup for HandleGroup in handle_list if HandleGroup]# 如果还有根就继续遍历,否则输出树if handle_list:return cls.show_all_windows(window=handle_list[-1][0], handle_list=handle_list, handle_dict=handle_dict)else:return handle_dict@classmethoddef find_handle_path(cls, hwnd_spy, num):"""寻找特定窗口的寻找路径找到全部层级的对应关系,然后反向搜索:param hwnd_spy: 窗口句柄(十六进制):param num: 窗口所属index,在spy++内查看:return:parent_window:顶层窗口target_path:路径的index"""all_path = cls.show_all_windows()key = tuple(list(cls.window_attr(int(hwnd_spy))) + [num])handle_path = [key]while True:key = all_path[key]if not key:handle_path = handle_path[::-1]parent_window = handle_path[0]target_path = [(i[-1]) for i in handle_path[1:]]return parent_window, target_pathhandle_path.append(key)@classmethoddef find_target_handle(cls, window, path):"""递归寻找子窗口的句柄:param window: 祖父窗口的完整句柄 (WindowName, ClassName, HwndPy, HwndSpy):param path: 子窗口列表:return: 目标窗口的完整属性"""for i in range(len(path)):window = cls.find_sub_windows(window[2], index=path[i])return window

Use

1、获取窗体属性

# 获取句柄1902690的属性
window = PySpy.window_attr(hwnd_py=1902690)
print(window)
Window(caption='百度云', class_name='ATL:011386F8', hwnd_py=1902690, hwnd_spy='0x1d0862')

2、获取全部顶层窗体

# 获取全部顶层窗体
windows = PySpy.show_top_windows()[:5]
for w in windows:print(w)
Window(caption='', class_name='ForegroundStaging', hwnd_py=66032, hwnd_spy='0x101f0')
Window(caption='', class_name='ForegroundStaging', hwnd_py=65982, hwnd_spy='0x101be')
Window(caption='', class_name='tooltips_class32', hwnd_py=65836, hwnd_spy='0x1012c')
Window(caption='', class_name='tooltips_class32', hwnd_py=65844, hwnd_spy='0x10134')
Window(caption='', class_name='tooltips_class32', hwnd_py=65856, hwnd_spy='0x10140')

3、查找指定的顶层窗体

# 查找顶层窗体
result = PySpy.find_top_window(caption='spy++')
print(result)
[Window(caption='spy++', class_name='CabinetWClass', hwnd_py=9571640, hwnd_spy='0x920d38')]

4、查找特定父窗体下全部子窗体

# 查找特定句柄下全部子窗体
window = PySpy.find_sub_windows(hwnd_py=9571640)
for w in windows:print(w)
Window(caption='', class_name='ForegroundStaging', hwnd_py=66032, hwnd_spy='0x101f0')
Window(caption='', class_name='ForegroundStaging', hwnd_py=65982, hwnd_spy='0x101be')
Window(caption='', class_name='tooltips_class32', hwnd_py=65836, hwnd_spy='0x1012c')
Window(caption='', class_name='tooltips_class32', hwnd_py=65844, hwnd_spy='0x10134')
Window(caption='', class_name='tooltips_class32', hwnd_py=65856, hwnd_spy='0x10140')

5、获取全部窗体父子对应关系

# 生成窗口全部对应的关系
windows = PySpy.show_all_windows(window=('spy++', 'CabinetWClass', 9571640, '0x920d38'))
for w in windows.items():print(w)
(('UIRibbonDockLeft', 'UIRibbonCommandBarDock', 1838390, '0x1c0d36', 0), ('spy++', 'CabinetWClass', 9571640, '0x920d38'))
(('UIRibbonDockRight', 'UIRibbonCommandBarDock', 1773536, '0x1b0fe0', 1), ('spy++', 'CabinetWClass', 9571640, '0x920d38'))
(('UIRibbonDockTop', 'UIRibbonCommandBarDock', 2756588, '0x2a0fec', 2), ('spy++', 'CabinetWClass', 9571640, '0x920d38'))
...
(('', 'ScrollBar', 52956100, '0x3280bc4', 0), ('', 'CtrlNotifySink', 3607746, '0x370cc2', 1))
(('', 'ReBarWindow32', 11603876, '0xb10fa4', 0), ('', 'WorkerW', 2755884, '0x2a0d2c', 1))
(('', 'ToolbarWindow32', 2427436, '0x250a2c', 0), ('', 'ReBarWindow32', 11603876, '0xb10fa4', 0))

6、获取特定窗体的查找路径

# 寻找特定窗口的寻找路径
parent, pth = PySpy.find_handle_path(hwnd_spy=0xb10fa4, num=0)
print(parent, pth)
('spy++', 'CabinetWClass', 9571640, '0x920d38', 232) [5, 1, 0]

7、根据查找路径获取到句柄信息(6的逆过程)

# 根据顶层窗体和路径 寻找子窗口的句柄
window = PySpy.find_target_handle(window=parent, path=pth)
print(window)
('', 'ReBarWindow32', 11603876, '0xb10fa4', 0)

8、根据窗体句柄,找到窗体位置

# 根据句柄定位窗体
x, y, m, n = win32gui.GetWindowRect(9571640)
pyautogui.moveTo((x + m) / 2, (y + n) / 2)


欢迎关注~ SandQuant 专注于全球金融数据和量化投资策略

【Python】Spy++使用相关推荐

  1. python下的spectral模块(高光谱图像处理)

    Spectral Python (SPy)是一个用于处理高光谱图像数据的纯Python模块.它具有读取.显示.操作和分类高光谱图像的功能. 之所以用它是因为这个对多波段图像的支持更好 参考 一.SPy ...

  2. spectral安装

    Spectral Python (SPy) 是一个纯 Python 模块,用于处理高光谱图像数据.它具有读取.显示.操作和分类高光谱图像的功能. SPy 需要 Python 并依赖于其他几个免费提供的 ...

  3. 1.2 InSAR数据处理之软件介绍

    本节内容主要分为两部分,分别是: 1.Windows操作系统下的软件介绍. 2.Linux系统下的软件介绍. 许多InSAR数据处理软件只能安装于Linux操作系统上,但有一部分软件既能够支持Linu ...

  4. 有用的URL,大量的干货!!!!!!!!!!!!

    这篇不算提供技术,笔者之前收藏了很多有用的学习资料URL,拿出来供大家共享!!!!!!!!! PythonTab:Python中文开发者社区门户 http://www.pythontab.com/ P ...

  5. Introspection in Python How to spy on your Python objects Guide to Python introspection

    什么是自省? 在日常生活中,自省(introspection)是一种自我检查行为. 在计算机编程中,自省是指这种能力:检查某些事物以确定它是什么.它知道什么以及它能做什么.自省向程序员提供了极大的灵活 ...

  6. 在 Python 中使用蒙特卡罗方法预测股票价格,使用蒙特卡罗模拟确定明年 SPY 最有可能的价格

    股票市场是历史上研究最多的领域之一.几十年来,人们一直在努力预测未来的价格.大多数人(如果不是全部)都在为这项任务而苦苦挣扎,因为股票市场是一个随机过程.由于其随机性,随机过程本质上很难或不可能准确预 ...

  7. 破纪录了!用 Python 实现自动扫雷!

    用Python+OpenCV实现了自动扫雷,突破世界记录,我们先来看一下效果吧. 中级 - 0.74秒 3BV/S=60.81 相信许多人很早就知道有扫雷这么一款经典的游(显卡测试)戏(软件),更是有 ...

  8. Python+OpenCV实现自动扫雷,挑战扫雷世界记录!

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转载自知乎Artrix https://zhuanlan.zh ...

  9. Python+OpenCV实现自动扫雷,创造属于自己的世界记录!

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转载自知乎Artrix https://zhuanlan.zh ...

  10. python语言type board_菜鸟学Python,双手奉上老司机给上路新手总结的Python实战问题……...

    针对Python这一话题每天后台都会有不少小伙伴提出问题,下面我就将这些问题进行汇整,产出"Python实战问题篇",我认为这些问题非常具有代表性,希望可以帮到大家. 第一类问题: ...

最新文章

  1. TensorFlow Serving 尝尝鲜
  2. 17、有名管道与无名管道之间的区别
  3. WPF 文本框添加水印效果
  4. wampserver3.0.6 外网 不能访问
  5. linux系统打开m3u8文件,M3U8 文件扩展名: 它是什么以及如何打开它?
  6. c语言交通违章编程代码,C语言程序设计之交通处罚单管理系统 报告(内含代码).doc...
  7. 哈希桶 entry_聊一聊面试常问的几大哈希算法问题,这些你都会了嘛??
  8. paip.mysql error2003 Can''t connect to MySQL server on localhost (10061)的解决
  9. 百度换肤怎么实现的html,JavaScript 实现百度换肤功能
  10. 参考文献中英文人名_参考文献中英文人名的写法
  11. 相机等效焦距和视场角计算
  12. Vulkan规范笔记(一) 第一章至第六章
  13. chrome插件安装
  14. Ant Design 编写登录和注册页面
  15. openfalcon 组件监控_使用滴滴云快速搭建 Open-Falcon 监控平台
  16. 本地git的分支名称变空的处理方法
  17. 仿微同商城后台API
  18. ip地址大全_2020全球公共 DNS 服务器 IP 地址大全
  19. 【NLP】第12章 检测客户情绪以做出预测
  20. 什么是电力物联网?为什么要建造电力物联网云平台?——安科瑞 严新亚

热门文章

  1. 计算机组装实验硬盘分区方法,硬盘怎么分区和格式化 史上最详细的硬盘分区方法大全 (全文)...
  2. PicoNeo开发中遇到的问题(一)
  3. 10个精选国外免费空间
  4. 对面积和坐标的曲面积分
  5. 服务器、网站被攻击了怎么办?
  6. MIMO系统如何获得分集增益(1)
  7. 网络基础之网络协议篇(转自林海峰老师)
  8. 计算机二级vb考试查分,计算机二级vb考试分值
  9. TPS和QPS的区别和理解
  10. css display:flex 属性