python中win32gui库常用函数
常用函数
获取所有窗口信息
通过win32gui.EnumWindows(_callback, windows)获取所有窗口信息
传入回调函数和容器即可
win32gui.GetWindowText(hwnd) 获取窗口标题栏文本
win32gui.GetClassName(hwnd)获取窗口类名
def get_all_windows():
"""
获取所有可见的顶层窗口信息。
注意:
- EnumWindows 仅枚举【顶层窗口】,不包含子控件(如按钮、输入框)。
若需获取子窗口,请使用 win32gui.EnumChildWindows(parent_hwnd, callback, param)。
- 返回结果仅包含可见窗口,系统隐藏窗口(如 Default IME)已被过滤。
"""
def _callback(hwnd, result):
"""
EnumWindows 回调函数,每找到一个顶层窗口时被系统自动调用。
Args:
hwnd: 当前窗口的句柄(整数标识符)
result: 由 EnumWindows 第二个参数透传进来的列表容器
"""
# 【过滤】跳过不可见窗口,避免返回大量无意义的系统隐藏窗口
if win32gui.IsWindowVisible(hwnd):
title = win32gui.GetWindowText(hwnd) # 获取窗口标题栏文本
cls = win32gui.GetClassName(hwnd) # 获取窗口类名(标识窗口类型,如 Chrome_WidgetWin_1)
result.append({
"hwnd": hwnd,
"title": title,
"class": cls,
})
# ⚠️ 【关键】回调函数必须返回 True!
# 若忘记返回或返回 False/None,EnumWindows 会在处理完当前窗口后立即停止枚举,
# 且不会抛出任何错误提示,这是新手最常遇到的隐蔽 Bug。
return True
windows = []
# 启动顶层窗口枚举,windows 列表会作为第二个参数传入回调函数的 result 参数
win32gui.EnumWindows(_callback, windows)
return windows
查找指定title的窗口
# 定义要查找的目标窗口标题(需与窗口实际标题完全一致,包括空格和标点)
title = "永远的蔚蓝星球"
# 通过窗口标题精确查找窗口句柄
# 第一个参数为窗口类名,传 None 表示不限类名,仅按标题匹配
# 返回值 hwnd 为窗口句柄(整数),未找到时返回 0
hwnd = win32gui.FindWindow(None, title)
# 判断是否成功找到窗口(0 在布尔上下文中为 False)
if hwnd:
# 找到窗口,打印窗口标题和对应句柄
print(f"找到了窗口<{title}>,句柄:{hwnd}")
else:
# 未找到匹配标题的窗口,提示用户检查标题是否正确或窗口是否已打开
print(f"没找到窗口<{title}>")
判断窗口是否最小化
min_win = win32gui.IsIconic(hwnd)
print(f"窗口<{title}>是否最小化:{'是' if min_win else '否'}")
判断窗口是否可见
visible = win32gui.IsWindowVisible(hwnd)
print(f"窗口<{title}>是否可见:{'是' if visible else '否'}")
获取窗口坐标
# 获取窗口坐标
rect = win32gui.GetWindowRect(hwnd)
print(f"窗口<{title}>坐标:{rect}")
# 返回值含义:(left, top, right, bottom) 分别代表窗口左、上、右、下边缘相对于屏幕左上角(0, 0) 的像素坐标。
# 宽高计算:width = right - left,height = bottom - top
设置窗口置顶显示
def safe_set_topmost(hwnd):
"""
安全地将窗口置顶(始终显示在其他普通窗口之上)。
Args:
hwnd: 目标窗口句柄
Returns:
bool: True 表示操作成功或窗口已处于置顶状态;False 表示句柄无效
"""
# 校验窗口句柄是否有效,避免对已销毁的窗口操作导致异常
if not win32gui.IsWindow(hwnd):
return False
# 如果窗口处于最小化状态,先恢复到正常状态
# 原因:最小化窗口无法被真正置顶,且后续获取坐标/尺寸会返回缓存值
if win32gui.IsIconic(hwnd):
win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
# 使用 SetWindowPos 设置 Z 序为 HWND_TOPMOST
# SWP_NOMOVE | SWP_NOSIZE:仅改变 Z 序,不移动窗口也不调整大小
win32gui.SetWindowPos(
hwnd, win32con.HWND_TOPMOST,
0, 0, 0, 0,
win32con.SWP_NOMOVE | win32con.SWP_NOSIZE
)
return True
设置窗口居中并且置顶显示
def safe_center_and_topmost(hwnd):
"""
安全地将窗口居中到当前所在显示器的工作区并置顶。
自动处理最小化状态、多显示器环境和 DPI 缩放。
Args:
hwnd: 目标窗口句柄
Returns:
bool: True 表示操作成功;False 表示句柄无效
"""
if not win32gui.IsWindow(hwnd):
return False
# 1. 最小化窗口必须先恢复,否则 GetWindowRect 返回的是历史缓存坐标
# 直接用缓存坐标计算会导致居中位置完全错误
if win32gui.IsIconic(hwnd):
win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
# 2. 获取窗口当前所在显示器的工作区(排除任务栏区域)
# MONITOR_DEFAULTTONEAREST:多显示器下自动定位窗口实际所在的屏幕
monitor = win32api.MonitorFromWindow(hwnd, win32con.MONITOR_DEFAULTTONEAREST)
monitor_info = win32api.GetMonitorInfo(monitor)
work_area = monitor_info['Work'] # (left, top, right, bottom)
# 3. 获取窗口当前的像素尺寸
rect = win32gui.GetWindowRect(hwnd)
win_w = rect[2] - rect[0]
win_h = rect[3] - rect[1]
# 4. 基于工作区(而非整个屏幕物理分辨率)计算居中坐标
# 使用 Work 而非 Monitor 避免窗口被任务栏遮挡或视觉上偏下
x = work_area[0] + (work_area[2] - work_area[0] - win_w) // 2
y = work_area[1] + (work_area[3] - work_area[1] - win_h) // 2
# 5. 单次 SetWindowPos 同时完成移动 + 置顶
# 分两步调用(先 MoveWindow 再 SetWindowPos)会产生两帧中间状态导致可见闪烁
# 此处不设 SWP_NOMOVE/SWP_NOSIZE,因为本次需要同时改变位置和 Z 序
win32gui.SetWindowPos(
hwnd, win32con.HWND_TOPMOST,
x, y, win_w, win_h,
0
)
return True
取消窗口置顶显示
def safe_clear_topmost(hwnd):
"""
取消窗口的置顶状态,恢复为普通 Z 序。
Args:
hwnd: 目标窗口句柄
Returns:
bool: True 表示操作成功或窗口已非置顶;False 表示句柄无效
"""
if not win32gui.IsWindow(hwnd):
return False
# 将 Z 序设为 HWND_NOTOPMOST,移除置顶属性
# 同样使用 NOMOVE | NOSIZE 避免意外改变窗口位置和尺寸
win32gui.SetWindowPos(
hwnd, win32con.HWND_NOTOPMOST,
0, 0, 0, 0,
win32con.SWP_NOMOVE | win32con.SWP_NOSIZE
)
return True
最大化显示
def safe_maximize(hwnd):
"""
安全地最大化窗口。自动处理最小化状态,避免异常显示。
Args:
hwnd: 目标窗口句柄
Returns:
bool: True 表示操作成功或窗口已最大化;False 表示句柄无效
"""
if not win32gui.IsWindow(hwnd):
return False
# ⚠️ 关键:最小化窗口直接调用 SW_MAXIMIZE 会导致"最小化+最大化"异常状态
# 表现为任务栏图标闪烁但窗口不可见,必须先恢复再最大化
if win32gui.IsIconic(hwnd):
win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
# SW_MAXIMIZE:最大化到当前所在显示器的全部工作区
win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
return True
最小化显示
def safe_minimize(hwnd):
"""
安全地最小化窗口。跳过已最小化的窗口,避免重复触发消息回调。
Args:
hwnd: 目标窗口句柄
Returns:
bool: True 表示操作成功或窗口已最小化;False 表示句柄无效
"""
if not win32gui.IsWindow(hwnd):
return False
# 幂等守卫:已最小化则直接返回,避免对 WPF/Electron 等框架触发多余动画
if win32gui.IsIconic(hwnd):
return True
# SW_MINIMIZE:仅改变状态为最小化,不强制激活窗口(保持当前前台窗口不变)
# 如需最小化同时激活窗口,应改用 SW_SHOWMINIMIZED
win32gui.ShowWindow(hwnd, win32con.SW_MINIMIZE)
return True
取消最大化或者最小化
def safe_restore(hwnd):
"""
取消窗口的最大化或最小化状态,将其恢复至正常显示状态。
若窗口已处于正常状态,则不执行任何操作。
Args:
hwnd: 目标窗口句柄。
Returns:
bool: True 表示操作成功或窗口已处于正常状态;
False 表示窗口句柄无效。
"""
# 校验窗口句柄有效性
if not win32gui.IsWindow(hwnd):
return False
# 既非最小化也非最大化,无需处理
if not win32gui.IsIconic(hwnd) and win32gui.GetWindowPlacement(hwnd)[1] != win32con.SW_SHOWMAXIMIZED:
return True
# SW_RESTORE: 取消最大化/最小化,恢复至上一次正常状态的尺寸与位置
# ⚠️ 不可使用 SW_SHOWNORMAL,该标志会重置窗口为默认初始尺寸
win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
return True

浙公网安备 33010602011771号