Python 通过 WindowsAPI 获取托盘图标区域句柄

引言

最近在做一个任务栏托盘监控的一个小工具,用到了Windows的API,值得记录一下,主要是为了获取托盘图标所在区域的矩阵,但是确定其位置是个麻烦事。

思路&步骤

因为每重启一次explorer就会重新创建窗体,所以句柄每次也会不一样

  1. 通过wndspy获取到托盘图标位置的窗体
  2. 查看其类名和标题
  3. 通过类名或标题来确定其句柄
  4. 通过句柄来获取窗口所在的位置信息

image.png

窗体标题和类名已经确定好了,接下来通过findWindow函数,通过类名ToolbarWindow32查句柄,结果返回值是0,这就很奇怪,明明是0x0014035E

那就换一个思路,枚举所有的窗口。

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

结果是没有找到,无论是通过标题还是类名

那就试试枚举所有子窗口呢?

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
这样就可以获取到,那么说明一个问题,第一次使用的是EnumWindows,而第二次使用的是EnumChildWindows,这两个函数不同点就是多了个Child,通过对比,有Child的得到的数据是更多的

函数解释

GetDesktopWindow 函数 (winuser.h)

检索桌面窗口的句柄。 桌面窗口覆盖整个屏幕。 桌面窗口是绘制其他窗口顶部的区域。

findWindowExW 函数 (winuser.h)

检索一个窗口的句柄,该窗口的类名和窗口名称与指定的字符串匹配。 该函数搜索子窗口,从指定子窗口后面的子窗口开始。 此函数不执行区分大小写的搜索。

FindWindowW 函数 (winuser.h)

检索顶级窗口的句柄,该窗口的类名称和窗口名称与指定的字符串匹配。 此函数不搜索子窗口。 此函数不执行区分大小写的搜索。

若要搜索子窗口,请从指定的子窗口开始,请使用FindWindowEx函数。

哭辽,官方文档上写的清清楚楚的。真是凄凄惨惨戚戚了。

来吧,展示

那么我们要确定托盘图标区域是谁的子窗口,甚至是多重嵌套。
image.png

根据上图就可以写出以下代码

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)

评论 0

还没有评论,来说点什么吧。

提交后需要审核才会公开。