Loading... # 引言 最近在做一个任务栏托盘监控的一个小工具,用到了Windows的API,值得记录一下,主要是为了获取托盘图标所在区域的矩阵,但是确定其位置是个麻烦事。 # 思路&步骤 因为每重启一次explorer就会重新创建窗体,所以句柄每次也会不一样 1. 通过wndspy获取到托盘图标位置的窗体 2. 查看其类名和标题 3. 通过类名或标题来确定其句柄 4. 通过句柄来获取窗口所在的位置信息 ![image.png](https://www.zunmx.top/usr/uploads/2022/10/2464308725.png) 窗体标题和类名已经确定好了,接下来通过findWindow函数,通过类名`ToolbarWindow32`查句柄,结果返回值是0,这就很奇怪,明明是`0x0014035E` 那就换一个思路,枚举所有的窗口。 ```python import win32gui hwndChildList = [] win32gui.EnumWindows(lambda hwnd, param: param.append(hwnd), hwndChildList) print(hwndChildList) for hwnd in hwndChildList: print("句柄:", hwnd, "标题:", win32gui.GetWindowText(hwnd), "类名", win32gui.GetClassName(hwnd)) ``` ![image.png](https://www.zunmx.top/usr/uploads/2022/10/2423632394.png) 结果是没有找到,无论是通过标题还是类名 那就试试枚举所有子窗口呢? ```python import win32gui hwndChildList = [] hd = win32gui.GetDesktopWindow() win32gui.EnumChildWindows(hd, lambda hwnd, param: param.append(hwnd), hwndChildList) print(hwndChildList) for hwnd in hwndChildList: print("句柄:", hwnd, "标题:", win32gui.GetWindowText(hwnd), "类名", win32gui.GetClassName(hwnd)) ``` ![image.png](https://www.zunmx.top/usr/uploads/2022/10/523638701.png) 这样就可以获取到,那么说明一个问题,第一次使用的是EnumWindows,而第二次使用的是EnumChildWindows,这两个函数不同点就是多了个Child,通过对比,有Child的得到的数据是更多的 ## 函数解释 GetDesktopWindow 函数 (winuser.h) > 检索桌面窗口的句柄。 桌面窗口覆盖整个屏幕。 桌面窗口是绘制其他窗口顶部的区域。 findWindowExW 函数 (winuser.h) > 检索一个窗口的句柄,该窗口的类名和窗口名称与指定的字符串匹配。 该函数搜索子窗口,从指定子窗口后面的子窗口开始。 此函数不执行区分大小写的搜索。 FindWindowW 函数 (winuser.h) > 检索顶级窗口的句柄,该窗口的类名称和窗口名称与指定的字符串匹配。 此函数不搜索子窗口。 此函数不执行区分大小写的搜索。 若要搜索子窗口,请从指定的子窗口开始,请使用FindWindowEx函数。 哭辽,官方文档上写的清清楚楚的。真是凄凄惨惨戚戚了。 # 来吧,展示 那么我们要确定托盘图标区域是谁的子窗口,甚至是多重嵌套。 ![image.png](https://www.zunmx.top/usr/uploads/2022/10/1281058346.png) 根据上图就可以写出以下代码 ```python shell_hwnd = win32gui.FindWindow("Shell_TrayWnd", None) notify_hwnd = win32gui.FindWindowEx(shell_hwnd, 0, "TrayNotifyWnd", None) toolbar = win32gui.FindWindowEx(notify_hwnd, 0, "SysPager", None) tray_hwnd = win32gui.FindWindowEx(toolbar, 0, self.trayClassName, None) ``` © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏