引言
最近在做一个任务栏托盘监控的一个小工具,用到了Windows的API,值得记录一下,主要是为了获取托盘图标所在区域的矩阵,但是确定其位置是个麻烦事。
思路&步骤
因为每重启一次explorer就会重新创建窗体,所以句柄每次也会不一样
- 通过wndspy获取到托盘图标位置的窗体
- 查看其类名和标题
- 通过类名或标题来确定其句柄
- 通过句柄来获取窗口所在的位置信息

窗体标题和类名已经确定好了,接下来通过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))

结果是没有找到,无论是通过标题还是类名
那就试试枚举所有子窗口呢?
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))

这样就可以获取到,那么说明一个问题,第一次使用的是EnumWindows,而第二次使用的是EnumChildWindows,这两个函数不同点就是多了个Child,通过对比,有Child的得到的数据是更多的
函数解释
GetDesktopWindow 函数 (winuser.h)
检索桌面窗口的句柄。 桌面窗口覆盖整个屏幕。 桌面窗口是绘制其他窗口顶部的区域。
findWindowExW 函数 (winuser.h)
检索一个窗口的句柄,该窗口的类名和窗口名称与指定的字符串匹配。 该函数搜索子窗口,从指定子窗口后面的子窗口开始。 此函数不执行区分大小写的搜索。
FindWindowW 函数 (winuser.h)
检索顶级窗口的句柄,该窗口的类名称和窗口名称与指定的字符串匹配。 此函数不搜索子窗口。 此函数不执行区分大小写的搜索。
若要搜索子窗口,请从指定的子窗口开始,请使用FindWindowEx函数。
哭辽,官方文档上写的清清楚楚的。真是凄凄惨惨戚戚了。
来吧,展示
那么我们要确定托盘图标区域是谁的子窗口,甚至是多重嵌套。

根据上图就可以写出以下代码
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
还没有评论,来说点什么吧。