[Python进阶] WindowsAPI:pywin32.win32gui

6.25 WindowsAPI:pywin32.win32gui

win32gui中定义了一些有关图形操作的API,例如FindWindow、PostMessage等。win32gui中的API多达几百个,这里我们挑选一些比较重要且常用的来介绍。

6.25.1 FindWindow

通过类名和标题搜索窗体并返回句柄

FindWindow(lpClassName=None, lpWindowName=None)

描述:
自顶层窗口(也就是桌面)开始搜索条件匹配的窗体,并返回这个窗体的句柄。不搜索子窗口、不区分大小写。找不到就返回0
参数:
lpClassName:字符型,是窗体的类名,这个可以在Spy++里找到。
lpWindowName:字符型,是窗口名,也就是标题栏上你能看见的那个标题。
说明:
1、找到了主窗口以后就靠它来定位子窗体,该函数只能搜索顶层窗口。
2、若子窗口不以窗口句柄的形式创建(windowless),只是逻辑上的窗口,绘制在父窗口之上。这种情况是只能定位到主窗口的。比如微信。
3、若lpClassName=None或lpWindowName=None,则表示对这两个参数不做匹配要求,返回第一个匹配到的窗口。
窗口的类名和打开的程序相关,和文件无关。如下:

文件格式/程序类名
记事本Notepad
360浏览器360se6_Frame
IE浏览器IEFrame
Excel2016标准版XLMAIN
UCwxWindowNR
谷歌浏览器Chrome_WidgetWin_1
pycharmSunAwtFrame
word2016标准版OpusApp
微信WeChatMainWndForPC
百度云盘DuiHostWnd
Notepad++Notepad++
企业微信WeWorkWindow

示例1:通过类和标题查找企业微信窗口句柄

import win32gui
from icecream import ic

handle = win32gui.FindWindow('WeWorkWindow', '企业微信')
ic(handle, hex(handle))

11:03:54|> handle: 68028, hex(handle): ‘0x109bc’

示例2:通过类查找谷歌浏览器窗口句柄

import win32gui
from icecream import ic

handle = win32gui.FindWindow('Chrome_WidgetWin_1', None)
ic(handle, hex(handle))

11:06:18|> handle: 66520, hex(handle): ‘0x103d8’

这里同时也输出了目标窗口句柄的16进制,方便和spy++软件查找的结果对照。

6.25.2 FindWindowEx

检索其类名和窗口名称与指定字符串匹配的窗口的句柄。该函数搜索子窗口,从给定的子窗口之后开始。
参数:
hwndParent:标识要搜索子窗口的父窗口。如果【hwndParent】为None,该函数将使用桌面窗口作为父窗口。该函数将在桌面的子窗口中进行搜索。
hwndChildAfter:标识子窗口。搜索从Z顺序中的下一个子窗口开始。【hwndChildAfter】必须是【hwndParent】的直接子窗口,而不仅仅是后代窗口。如果【hwndChildAfter】为None,则搜索从第一个子窗口【hwndParent】开始。请注意,如果【hwndParent】和【hwndChildAfter】均为None,则该函数将搜索所有顶级窗口。
lpszClasspl:要搜索的窗口类名。
lpszWindow:要搜索的窗口标题。
注意:
若lpszClasspl =None或lpszWindow =None,则表示对这两个参数不做匹配要求,返回第一个匹配到的窗口。

import win32gui
from icecream import ic

handle = win32gui.FindWindowEx(None, None, 'Notepad', None)  # 在顶层窗口中搜索`记事本`窗口
ic(handle, hex(handle))
handle = win32gui.FindWindowEx(handle, None, 'Edit', None)  # 在`记事本`窗口中搜索`Edit`窗口
ic(handle, hex(handle))

11:25:40|> handle: 659030, hex(handle): ‘0xa0e56’
11:25:40|> handle: 855762, hex(handle): ‘0xd0ed2’

6.25.3 GetParent

获取子窗口的父窗口句柄

import win32gui

child_handle = 69136
parent_handle = win32gui.GetParent(child_handle)
print(parent_handle)

6.25.4 GetWindowRect

返回窗口的边界矩形的尺寸。尺寸以相对于屏幕左上角的屏幕坐标给出。
注意:窗口不能是最小化到任务栏,否则返回的尺寸会是负数。

import win32gui
from icecream import ic

handle = win32gui.FindWindowEx(None, None, 'Notepad', None)  # 在顶层窗口中搜索`记事本`窗口
ic(handle, hex(handle))
left, top, right, bottom = win32gui.GetWindowRect(handle)
ic(left, top, right, bottom)

11:29:24|> handle: 659030, hex(handle): ‘0xa0e56’
11:29:24|> left: 843, top: 132, right: 1502, bottom: 698

6.25.5 GetWindowText

获取窗口标题

import win32gui
from icecream import ic

handle = win32gui.FindWindowEx(None, None, 'Notepad', None)
ic(handle, hex(handle))
title = win32gui.GetWindowText(handle)
ic(title)

11:30:48|> handle: 659030, hex(handle): ‘0xa0e56’
11:30:48|> title: ‘Temp.txt - 记事本’

6.25.6 GetClassName

获取窗口的类

import win32gui

handle = 201008
class_name = win32gui.GetClassName(handle)
print(class_name)

6.25.7 IsWindow

判断某个整数是否是一个窗口的句柄。若是,则返回值不为0,否则返回0。

win32gui.IsWindow(hwnd)

6.25.8 IsWindowEnabled

确定是否为鼠标和键盘输入启用了指定的窗口。窗口可用。
返回值:如果启用该窗口,则返回值不为零。如果窗口未启用,返回值为零。
备注:子窗口只有在启用和可见时才接收输入。

win32gui.IsWindowEnabled(hwnd)

6.25.9 IsWindowVisible

检索指定窗口的可见性状态(是否具有WS_VISIBLE样式)。
返回值:
如果指定的窗口及其父窗口具有WS_VISIBLE样式,则返回值不为零。
如果指定的窗口及其父窗口没有WS_VISIBLE样式,返回值为零。
因为返回值指定窗口是否具有WS_VISIBLE样式,即使窗口完全被其他窗口遮挡,它也可能非零。
备注
窗口的可见性状态由WS_VISIBLE样式位指示。设置WS_VISIBLE时,只要窗口具有WS_VISIBLE样式,将显示该窗口,并显示其后续绘图。
如果窗口被其他窗口遮挡或被其父窗口剪裁,任何绘制到具有WS_VISIBLE样式的窗口将不会显示。

win32gui.IsWindowVisible(hwnd)

6.25.10 EnumWindows

通过将每个窗口的句柄依次传递给应用程序定义的回调函数来枚举屏幕上的所有顶级窗口。EnumWindows继续,直到最后一个顶级窗口被枚举或回调函数返回FALSE。
示例1:遍历windows下所有句柄及窗口名称

from icecream import ic
import win32gui

hwnd_title = dict()


def get_all_hwnd(hwnd, mouse):
    if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
        hwnd_title.update({hwnd: win32gui.GetWindowText(hwnd)})


win32gui.EnumWindows(get_all_hwnd, 0)
for handle, title in hwnd_title.items():
    if title:
        ic(handle, title)

15:20:14|> handle: 986708, title: ‘t1.py – t5.py’
15:20:14|> handle: 921718, title: ‘Python - 进阶.docx - Word’
15:20:14|> handle: 659030, title: ‘Temp.txt - 记事本’
15:20:14|> handle: 1577106, title: ‘查找窗口’
15:20:14|> handle: 67000, title: ‘企业邮箱前台-邮箱 - 360安全浏览器 14.1’
15:20:14|> handle: 394748, title: ‘数据驱动.xlsm - Excel’
15:20:14|> handle: 68028, title: ‘企业微信’
15:20:14|> handle: 133664, title: ‘PythonFiles’
15:20:14|> handle: 983950, title: ‘spy - Everything’
15:20:14|> handle: 327756, title: ‘Microsoft Text Input Application’
15:20:14|> handle: 68710, title: ‘非常用工作文档.xlsm - Excel’
15:20:14|> handle: 66004, title: ‘Program Manager’

示例2:通过窗体标题模糊搜索并返回窗体句柄

from icecream import ic
import win32gui

hwnd_title = dict()


def get_all_hwnd(hwnd, mouse):
    if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
        hwnd_title.update({hwnd: win32gui.GetWindowText(hwnd)})


win32gui.EnumWindows(get_all_hwnd, 0)


def find_window(part_title):
    for hwnd, title in hwnd_title.items():
        if part_title in title:
            return hwnd


handle = find_window('企业微信')
ic(handle)

15:24:17|> handle: 68028

6.25.11 EnumChildWindows

通过将每个子窗口的句柄传递给应用程序定义的回调函数来枚举属于指定父窗口的子窗口,直到最后一个子窗口被枚举或回调函数返回FALSE。
示例1:获取主窗口句柄下的所有子孙窗口句柄

from icecream import ic
import win32gui

parent_handle = int('000A0E56', 16)


def get_children_window(parent):
    hwndChildList = []
    win32gui.EnumChildWindows(parent, lambda hwnd, param: param.append(hwnd), hwndChildList)
    return hwndChildList


child_list = get_children_window(parent_handle)
ic(child_list)

15:27:14|> child_list: [855762, 201106]

6.25.12 ShowWindow

激活显示窗口,根据第二个参数的不同改变窗口的不同状态。

import win32gui
import win32con

hwnd = 3806050
win32gui.ShowWindow(hwnd, win32con.SW_SHOWNORMAL)

其中ShowWindow 函数显示方式(第二个参数)定义如下

参数(win32con)意义备注
SW_HIDE隐藏窗口,大小不变,激活状态不变不光是窗口最小化,连任务栏里都不会存在
SW_MAXIMIZE最大化窗口,显示状态不变,激活状态不变
SW_MINIMIZE最小化窗口,显示状态不变,激活状态不变最小化窗口
SW_RESTORE从最大化或最小化恢复正常大小,显示状态不变,激活状态不变窗口恢复正常
SW_SHOW显示并激活窗口,大小状态不变sw_hide的反向操作。不过只是会在任务栏中显示,桌面上看不到窗口
SW_SHOWMAXIMIZED显示并激活窗口,以最大化显示
SW_SHOWMINIMIZED显示并激活窗口,以最小化显示
SW_SHOWMINNOACTIVE显示窗口并最小化,激活状态不变
SW_SHOWNA显示窗口,大小状态不变,激活状态不变和sw_show一样,没看出什么区别
SW_SHOWNOACTIVATE显示并从最大化或最小化恢复正常大小,激活状态不变显示窗口到正常大小,但不会前置
SW_SHOWNORMAL显示并激活窗口,恢复正常大小(初始化时用这个参数)显示窗口到正常大小,但不会前置

6.25.13 SetForegroundWindow

前置窗口

win32gui.SetForegroundWindow(hwnd)

6.25.14 Postmessage、SendMessage

函数功能:
该函数将一个消息放入(寄送)到与指定窗口创建的线程相联系消息队列里,Postmessage不等待线程处理消息就返回。而SendMessage则会一直等待处理完并返回处理结果。消息队列里的消息通过调用GetMessagePeekMessage取得。
函数原型:
B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
参数:
hWnd:其窗口程序接收消息的窗口的句柄。
Msg:指定被寄送的消息。
wParam:指定附加的消息特定的信息。
IParam:指定附加的消息特定的信息。
返回值:如果函数调用成功,返回非零值:如果函数调用失败,返回值是零。若想获得更多的错误信息,请调用GetLastError函数。

import win32gui

hwnd = int('000E0EE2', 16)
win32gui.SendMessage(0x00041192, win32con.WM_SETTEXT, None, 'hello world')  # 将hello world写入到记事本中
win32api.PostMessage(hwnd, win32con.WM_KEYDOWN, win32con.VK_F5, 0)  # 发送F5键到记事本中,将会写入当前时间
win32api.PostMessage(hwnd, win32con.WM_KEYUP, win32con.VK_F5, 0)
win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)  # 关闭窗口,将会询问是否要保存

  • 45
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 要在Python中添加pywin32,可以按照以下步骤操作: 1. 确认你已经安装了Python,可以在官方网站https://www.python.org/downloads/下载并安装最新版本。 2. 下载pywin32,可以在官方网站https://github.com/mhammond/pywin32/releases下载最新版本的pywin32。 3. 解压下载的pywin32压缩包,并进入解压后的文件夹。 4. 运行安装程序,双击运行“pywin32-XXX.win-amd64-pyYY.exe”(其中XXX是pywin32版本号,YY是Python的版本号)。 5. 按照安装程序的提示完成安装过程。 6. 安装完成后,你可以在Python中使用pywin32的功能,例如访问Windows API和COM对象等。 注意:在安装pywin32之前,建议先升级你的Python到最新版本,以确保与pywin32的兼容性。 ### 回答2: 要在Python中添加pywin32,可以按照以下步骤进行操作: 1. 首先,确保已经安装了Python。如果没有安装Python,可以从Python官方网站(https://www.python.org)下载并安装最新版本的Python。 2. 打开命令提示符(Windows上通过按下Win + R键,然后输入cmd并按下回车键来打开)或者终端(Mac和Linux上)。 3. 在命令提示符或终端中,使用以下命令来安装pywin32: ``` pip install pywin32 ``` 这会使用Python的包管理器pip自动下载和安装pywin32。 4. 安装完成后,可以在Python脚本中导入pywin32模块,并使用其中的功能了。 ```python import win32api import win32gui # 其他的pywin32模块导入和使用 ``` 这样就可以使用pywin32提供的功能了,例如操作窗口、注册表、文件系统等。 需要注意的是,安装pywin32时可能需要管理员权限。如果安装过程中遇到问题,可以尝试在命令提示符或终端中使用管理员权限运行安装命令,即在Windows上右键点击命令提示符并选择“以管理员身份运行”,或在Mac和Linux上使用sudo命令。 ### 回答3: 要在Python中添加pywin32模块,可以按照以下步骤进行: 1. 首先,确保已经安装了Python解释器。如果尚未安装,请从Python官方网站上下载并安装适用于您的操作系统的正确版本。 2. 打开命令提示符(Windows)或终端(Mac或Linux)。 3. 在命令提示符或终端中,键入以下命令来安装pywin32模块: ``` pip install pywin32 ``` 4. 按下回车键后,pip将开始下载和安装pywin32模块及其所有依赖项。请耐心等待,直到安装过程完成。 5. 验证安装是否成功,可以在Python交互式环境中执行以下命令: ```python import win32api ``` 如果没有出现错误提示,则表示pywin32模块已成功添加到Python中。 请注意,安装pywin32模块可能需要在具有管理员权限的命令提示符或终端中运行。如果遇到任何权限问题,请以管理员身份重新打开命令提示符或终端。 希望以上步骤能够帮助您成功添加pywin32模块到Python中。祝您使用Python编程愉快!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0思必得0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值