# pywin32库自动操作键鼠 **Repository Path**: gusong125/pywin32-auto ## Basic Information - **Project Name**: pywin32库自动操作键鼠 - **Description**: pywin32库自动操作键鼠,CSDN博主 ——发现你走远了 转载请说明原作者并放置链接 专栏传送门https://blog.csdn.net/u011027547/category_11976162.html 解读博文传送门https://blog.csdn.net/u011027547/article/details/126471190 - **Primary Language**: Python - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: https://blog.csdn.net/u011027547/article/details/126471190 - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 7 - **Created**: 2024-12-23 - **Last Updated**: 2024-12-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README @[toc](目录)
『python自动化』分享win32gui、cv2、easyocr等库相关的新手入门教程,目标是编写python程序进行自动化办公,解放双手。 > **欢迎关注 [『python自动化』 系列](https://blog.csdn.net/u011027547/category_11976162.html),持续更新中** > **欢迎关注 [『python自动化』 系列](https://blog.csdn.net/u011027547/category_11976162.html),持续更新中** 如果安装win32gui库遇到了困难,可以参考下文安装。 > [【python自动化】01.安装配置库和环境之win32gui安装失败(保姆级图文)](https://blog.csdn.net/u011027547/article/details/126450109) ## 源码和工具下载 ### 大漠综合工具->坐标和窗口信息抓取 - 大漠综合工具获取句柄和窗口信息 1.用十字标记拖动到需要的窗口(注意拖到大窗口而不是小窗口,是整个记事本窗口而不是记事本的输入区域的小窗口) 2.绑定(方便后续的操作) 3.点击属性即可查看窗口信息,包括窗口的大小、坐标、16进制句柄 ![在这里插入图片描述](https://img-blog.csdnimg.cn/c0d7267e9f2a4610ade5c17a854831d6.gif) 我们一般用的是16进制句柄,在这里查看 ![在这里插入图片描述](https://img-blog.csdnimg.cn/1847d405eaf84748b9cc0a91cca38377.png) - 坐标和色点采集 注意这里的相对坐标和绝对坐标,我们绑定了窗口后默认把窗口左上角(0,0)视为参考标准。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/579cc4623c854cf486ae877a0e8dcf94.gif) ### 在你的桌面上新建一个记事本用于后面的代码测试 ![在这里插入图片描述](https://img-blog.csdnimg.cn/58133a24a45f43c8ba85a2c8d7206568.png) ### 完整项目源码
## 实现思路 ### 介绍win32的基础思路 万物皆是窗口,首先获取窗口的句柄,然后再以此为基础对于窗口输送键鼠的命令。 ### 基本步骤 获取窗口句柄->激活窗口->设置窗口大小位置->激活聊天输入框->输入内容 ### API介绍 下面的代码实战会详细介绍每个方法的参数,也可以访问pywin32的官方文档查看。(建议这么做,因为以后我们自学其他库都要经历查看文档这个过程) ```python 官网网址 http://timgolden.me.uk/pywin32-docs/contents.html ```
## 代码实战 ### 1. 获取窗口句柄的三种方法 注意窗口类名, 窗口标题名两者必须至少有一个才能找到你想要的窗口,另一个可以缺省为None > 法1:win32gui.FindWindow(窗口类名, 窗口标题名)#直接查找窗口 > 实例:win32gui.FindWindow("Notepad", None) > 返回值:窗口的16进制句柄 ```python import win32gui #如果失败,要做好异常处理 #1.根据窗口标题获取句柄,通过标题查找,仅返回一个顶层窗口的句柄,不支持模糊查询 try: # 获取窗口句柄 handle = win32gui.FindWindow("Notepad", None)#通过窗口标题获取窗口句柄 print("窗口句柄是:{}".format(handle)) except Exception as e: print("窗口句柄获取失败:{}".format(e)) ``` > 法2:win32gui.FindWindowEx(父窗口句柄, 查找窗口顺序, 窗口类名, 窗口标题名)#根据父窗口查找子窗口 > 实例:win32gui.FindWindowEx(0, 0, "Notepad", None) > 父窗口句柄:如果为 0,则假定为桌面窗口 > 查找窗口顺序:子窗口后按Z顺序搜索,可以为0搜索全部 > 返回值:查找得到的子窗口窗口的16进制句柄 ```python #2.通过父窗口找子窗口,根据窗口类名和标题检索句柄,查找 # 参数 # 家长:PyHANDLE # 将搜索其子窗口的窗口。如果为 0,则假定为桌面窗口。 # ChildAfter : PyHANDLE # 子窗口后按Z顺序搜索,可以为0搜索全部 # 类名:PyResourceId # 要查找的窗口类的名称或原子,可以是 None # 窗口名称:字符串 # 要查找的窗口标题,可以是 None import win32gui try: # 获取窗口句柄 # handle = win32gui.FindWindowEx(0, 0, "Notepad", '新建文本文档.txt - 记事本') handle = win32gui.FindWindowEx(0, 0, "Notepad", None) #注意,当你修改了记事本后标题名字前加上了一个*变成了“*新建文本文档.txt - 记事本”,所以这里可以填写None缺省,只用类名查找 print("窗口句柄是:{}".format(handle)) except Exception as e: print("窗口句柄获取失败:{}".format(e)) ``` > 法3:win32gui.WindowFromPoint((窗口x坐标, 窗口y坐标))#根据窗口坐标查找顶层符合坐标要求的一个窗口 > 实例:win32gui.WindowFromPoint((0, 0)) > 窗口坐标是每个窗口都会有的属性,但是这个方法只会查找顶层的那一个窗口,所以说改变置顶窗口就会改变通过这个方法获取的窗口句柄,所以不建议用。 > 返回值:查找得到的子窗口窗口的16进制句柄 ```python #3.根据窗口左上角坐标获取句柄,(0, 0)只获取最顶层的左上角窗口,这种方法我个人不建议使用,因为顶层的窗口变化了,句柄就变化了 import win32gui try: # 获取窗口句柄 handle = win32gui.WindowFromPoint((0, 0)) print("窗口句柄是:{}".format(handle)) except Exception as e: print("窗口句柄获取失败:{}".format(e)) ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/8a52506e68004c4b80670fdf2f64e4fe.png) ### 2. 根据窗口句柄获取窗口信息 > #获取窗口信息 (x,y坐标,还有宽度,高度) > 原型:win32gui.GetWindowRect(窗口句柄) > 实例:handleMessage = win32gui.GetWindowRect(handle) > 返回值:handleMessage是一个元组,包含四个元素,结构是(x坐标,y坐标,宽度,高度) > #获取窗口标题 > 原型:win32gui.GetWindowText(窗口句柄) > 实例:win32gui.GetWindowText(handle) > 返回值:字符串,窗口标题 > #获取窗口类名 > 原型:win32gui.GetClassName(窗口句柄) > 实例:win32gui.GetClassName(handle) > 返回值:字符串,窗口类名 ```python import win32gui # 注意窗口句柄获取如果失败,要做好异常处理 try: # 获取窗口句柄 handle = win32gui.FindWindowEx(0, 0, "Notepad", None)# print("窗口句柄是:{}".format(handle)) except Exception as e: print("窗口句柄获取失败:{}".format(e)) # 注意窗口信息获取如果失败,要做好异常处理 try: # 获取窗口信息 (x,y坐标,还有宽度,高度) handleMessage = win32gui.GetWindowRect(handle)#通过窗口句柄获取窗口信息 print("窗口 x,y坐标,还有宽度,高度是:{}".format(handleMessage)) # 获取窗口标题 title = win32gui.GetWindowText(handle) print("窗口标题是:{}".format(title)) # 获取窗口类名 class_name = win32gui.GetClassName(handle) print("窗口类名是:{}".format(class_name)) except Exception as e: print("窗口信息获取失败:{}".format(e)) ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/cceda9510df349cfb47969cf2c527ad3.png)
### 3. 通过句柄设置窗口 > #设置窗口信息 > 原型:win32gui.MoveWindow(窗口句柄, 窗口左边界,窗口上边界,窗口宽度,窗口高度,确定窗口是否被刷新) > 实例:win32gui.MoveWindow(handle, 0, 0, 1280, 768, True) > 返回值:None ```python import win32gui # 注意窗口句柄获取如果失败,要做好异常处理 try: # 获取窗口句柄 handle = win32gui.FindWindowEx(0, 0, "Notepad", None)# print("窗口句柄是:{}".format(handle)) except Exception as e: print("窗口句柄获取失败:{}".format(e)) try: # 获取窗口信息 (x,y坐标,还有宽度,高度) handleMessage = win32gui.GetWindowRect(handle)#通过窗口句柄获取窗口信息 print("窗口 x,y坐标,还有宽度,高度是:{}".format(handleMessage)) # 获取窗口标题 title = win32gui.GetWindowText(handle) print("窗口标题是:{}".format(title)) # 获取窗口类名 class_name = win32gui.GetClassName(handle) print("窗口类名是:{}".format(class_name)) # 设置窗口 # 参数:句柄,窗口左边界,窗口上边界,窗口宽度,窗口高度,确定窗口是否被刷新 win32gui.MoveWindow(handle, 0, 0, 1280, 768, True) # 设置窗口后获取窗口信息,查看是否设置成功 handleMessage = win32gui.GetWindowRect(handle)#通过窗口句柄获取窗口信息 print("修改窗口后的窗口 x,y坐标,还有宽度,高度是:{}".format(handleMessage)) except Exception as e: print("窗口信息获取失败:{}".format(e)) ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/ac2177ab4b5645b086e5bbe848b71ee2.png)
### 4. 激活窗口 > #激活窗口 > 原型:win32gui.SetForegroundWindow(窗口句柄) > 实例:win32gui.SetForegroundWindow(handle) > 返回值:None ```python import win32gui # 注意窗口句柄获取如果失败,要做好异常处理 try: # 获取窗口句柄 handle = win32gui.FindWindowEx(0, 0, "Notepad", None)# print("窗口句柄是:{}".format(handle)) # 将创建指定窗口的线程设置到前台,并且激活该窗口 win32gui.SetForegroundWindow(handle) except Exception as e: print("窗口句柄获取失败或是前台设置失败:{}".format(e)) ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/2a971a57b1324842970a8f706088c423.png)
### 5. 鼠标信息的获取 > #获取鼠标位置 > 原型:win32api.GetCursorPos() > 实例:point_position = win32api.GetCursorPos() > 返回值:point_position 是一个元组,结构是(x坐标,y坐标) > #设置鼠标位置 > 原型:win32api.SetCursorPos((x坐标,y坐标)) > 实例:win32api.SetCursorPos((0, 0)) > 返回值:None ```python import win32gui import win32api # 注意窗口句柄获取如果失败,要做好异常处理 try: # 获取窗口句柄 handle = win32gui.FindWindowEx(0, 0, "Notepad", None)# print("窗口句柄是:{}".format(handle)) # 获取鼠标位置 point_position = win32api.GetCursorPos() print("鼠标位置是:{}".format(point_position)) # 设置鼠标位置 win32api.SetCursorPos((0, 0)) # 获取鼠标位置 point_position = win32api.GetCursorPos() print("设置后鼠标位置是:{}".format(point_position)) except Exception as e: print("窗口句柄获取失败或是前台设置失败:{}".format(e)) ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/f1647101b6d84af58e921fa83490a5c0.png)
### 6. 鼠标点击事件 鼠标点击分为点击和弹起2个过程。 > #按下鼠标左键 > 原型:win32api.mouse_event(键位操作, 0, 0) > 实例:win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0) > 返回值:None > #松开鼠标左键 > 原型:win32api.mouse_event(键位操作, 0, 0) > 实例:win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0) > 参数解读(dwFlags ,dx ,dy ,dwData ,dwExtraInfo) dwFlags=0:双字,指定各种功能选项的标志 dx:double类型,鼠标的水平位置 dy : double类型,鼠标的垂直位置 dwData:double类型,标志特定参数 dwExtraInfo=0:double类型,与鼠标事件相关的附加数据 > 返回值:None >#键位表 >MOUSEEVENTF_LEFTDOWN:表明接按下鼠标左键 MOUSEEVENTF_LEFTUP:表明松开鼠标左键 MOUSEEVENTF_RIGHTDOWN:表明按下鼠标右键 MOUSEEVENTF_RIGHTUP:表明松开鼠标右键 MOUSEEVENTF_MIDDLEDOWN:表明按下鼠标中键 MOUSEEVENTF_MIDDLEUP:表明松开鼠标中键 MOUSEEVENTF_WHEEL:鼠标轮移动,数量由data给出 ```python import win32api import win32con import win32gui # 注意窗口句柄获取如果失败,要做好异常处理 try: # 获取窗口句柄 handle = win32gui.FindWindowEx(0, 0, "Notepad", None)# print("窗口句柄是:{}".format(handle)) # 获取鼠标位置 point_position = win32api.GetCursorPos() print("鼠标位置是:{}".format(point_position)) # 模拟鼠标在(1000, 500)位置进行点击操作 point = (1000, 500) win32api.SetCursorPos(point) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0)#按下鼠标左键 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0)#松开鼠标左键 # 获取鼠标位置 point_position = win32api.GetCursorPos() print("鼠标位置是:{}".format(point_position)) except Exception as e: print("窗口句柄获取失败或是前台设置失败:{}".format(e)) ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/78b51697b30f43d7b127e0bc09a92bd2.png)
### 7. 键盘键位操作 键盘操作类似鼠标也分为按下和弹起2个过程。 有所区别的是,如果要输入内容,要先让鼠标激活输入框的焦点,所以要先点击一下。 同时也要注意一点,窗口操作最好加入一些延时,避免时序错误,导致出现先输入再激活焦点的错误,从而导致无法输入。 > #按下按键 > 原型:win32api.keybd_event(键码, 硬件扫描码, 按下还是弹起的标志位, 与击键相关的附加的32位值) > 实例:win32api.keybd_event(65, 0, KEYEVENTF_EXTENDEDKEY, 0)#按下A > 实例:win32api.keybd_event(65, 0, 0, 0)#按下A > 返回值:None > #弹起按键 > 原型:win32api.keybd_event(键码, 硬件扫描码, 按下还是弹起的标志位, 与击键相关的附加的32位值) > 实例:win32api.keybd_event(65, 0, win32con.KEYEVENTF_KEYUP, 0)#松开A > 实例:win32api.keybd_event(65, 0, 1, 0)#松开A > 返回值:None bVk:虚拟键码 bScan:硬件扫描码,一般设置为0即可 dwFlags:函数操作的一个标志位,如果值为KEYEVENTF_EXTENDEDKEY则该键被按下,也可设置为0即可,如果值为KEYEVENTF_KEYUP(也就是1)则该按键被释放 dwExtraInfo:定义与击键相关的附加的32位值,一般设置为0即可 ```python import win32gui import win32api import win32con # 注意窗口句柄获取如果失败,要做好异常处理 try: # 获取窗口句柄 handle = win32gui.FindWindowEx(0, 0, "Notepad", None)#桌面窗口的所有子窗口检索类名"Edit",标题为None的窗口 print("窗口句柄是:{}".format(handle)) # 设置窗口 # 参数:句柄,窗口左边界,窗口上边界,窗口宽度,窗口高度,确定窗口是否被刷新 win32gui.MoveWindow(handle, 0, 0, 500, 500, True) # 设置窗口后获取窗口信息,查看是否设置成功 handleMessage = win32gui.GetWindowRect(handle)#通过窗口句柄获取窗口信息 print("修改窗口后的窗口 x,y坐标,还有宽度,高度是:{}".format(handleMessage)) # 将创建指定窗口的线程设置到前台,并且激活该窗口 win32gui.SetForegroundWindow(handle) #加入延时,否则可能会操作失败 print("如果没有下面以这一行代码,可能无法正常输入A B 字母,这就是延时等待的作用") win32api.Sleep(1000) #激活窗口输入栏 # 模拟鼠标在(246,217)位置进行点击操作,这个坐标主要是点击一下txt记事本的输入窗口,激活焦点 point = (246,217) win32api.SetCursorPos(point) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0)#按下鼠标左键 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0)#松开鼠标左键 #加入延时,否则可能会操作失败 win32api.Sleep(1000) #在记事本中输入A B 字母 win32api.keybd_event(65, 0, 0, 0)#按下A win32api.keybd_event(66, 0, 0, 0)#按下B win32api.keybd_event(65, 0, win32con.KEYEVENTF_KEYUP, 0)#松开A win32api.keybd_event(66, 0, win32con.KEYEVENTF_KEYUP, 0)#松开B except Exception as e: print("窗口句柄获取失败或是前台设置失败:{}".format(e)) ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/1549d2a6c7bc4724a09b60d86940f634.png)
### 8. 延时等待 这一节的内容和第7节类似,就是让大家试试看,如果不加入延时会发生什么,强调一下延时的作用。 > #延时等待 > 原型:win32api.Sleep(等待毫秒) > 实例:win32api.Sleep(1000) > 返回值:None ```python import win32gui import win32api import win32con # 注意窗口句柄获取如果失败,要做好异常处理 try: # 获取窗口句柄 handle = win32gui.FindWindowEx(0, 0, "Notepad", None)#桌面窗口的所有子窗口检索类名"Edit",标题为None的窗口 print("窗口句柄是:{}".format(handle)) # 设置窗口 # 参数:句柄,窗口左边界,窗口上边界,窗口宽度,窗口高度,确定窗口是否被刷新 win32gui.MoveWindow(handle, 0, 0, 500, 500, True) # 设置窗口后获取窗口信息,查看是否设置成功 handleMessage = win32gui.GetWindowRect(handle)#通过窗口句柄获取窗口信息 print("修改窗口后的窗口 x,y坐标,还有宽度,高度是:{}".format(handleMessage)) # 将创建指定窗口的线程设置到前台,并且激活该窗口 win32gui.SetForegroundWindow(handle) #加入延时,否则可能会操作失败 print("如果没有下面以这一行代码,可能无法正常输入A B 字母,这就是延时等待的作用") win32api.Sleep(1000) #激活窗口输入栏 # 模拟鼠标在(246,217)位置进行点击操作 point = (246,217) win32api.SetCursorPos(point) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0)#按下鼠标左键 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0)#松开鼠标左键 #加入延时,否则可能会操作失败 print("如果没有下面以这一行代码,可能无法正常输入A B 字母,这就是延时等待的作用") win32api.Sleep(1000) #在记事本中输入A B 字母 win32api.keybd_event(65, 0, 0, 0)#按下A win32api.keybd_event(66, 0, 0, 0)#按下B win32api.keybd_event(65, 0, win32con.KEYEVENTF_KEYUP, 0)#松开A win32api.keybd_event(66, 0, win32con.KEYEVENTF_KEYUP, 0)#松开B except Exception as e: print("错误:{}".format(e)) ```
### 9. 剪切板操作 > #打开剪切板 > 原型:win32clipboard.OpenClipboard() > 实例:win32clipboard.OpenClipboard() > 返回值:None > #剪切板置空 > 原型:win32clipboard.EmptyClipboard() > 实例:win32clipboard.EmptyClipboard() > 置剪切板为空,赋初始值是程序员的好习惯,注意任何数据一开始的样子 > 返回值:None > #设置剪切板内容 > 原型:win32clipboard.SetClipboardText(消息内容, 要使用的剪贴板格式) > 实例:win32clipboard.SetClipboardText(send_message, win32clipboard.CF_TEXT) > 返回值:一串很长的数字,我猜测要么数据内容要么是内存地址(实际使用没有必要这么深究,大家有知道的评论区留言告知我) > SetClipboardText的2个参数解读: > - send_message ->文本:str / unicode 要放置在剪贴板上的文本。 win32clipboard.CF_TEXT ->格式 = CF_TEXT: > - 要使用的剪贴板格式 - 必须是CF_TEXT或CF_UNICODETEXT > #获取剪切板数据并转码为中文 > 原型:win32clipboard.GetClipboardData(剪贴板格式 ).decode(编码类型) > 实例:getResult= win32clipboard.GetClipboardData(win32clipboard.CF_TEXT).decode('GBK') > 返回值:getResult是字符串文本 > #关闭剪切板,有始有终,关闭以此减少资源占用 > 原型:win32clipboard.CloseClipboard() > 实例:win32clipboard.CloseClipboard() > 返回值:None ```python import win32clipboard import win32gui # 注意窗口句柄获取如果失败,要做好异常处理 try: # 获取窗口句柄 handle = win32gui.FindWindowEx(0, 0, "Notepad", None)#桌面窗口的所有子窗口检索类名"Edit",标题为None的窗口 print("窗口句柄是:{}".format(handle)) send_message = '发送的消息内容' win32clipboard.OpenClipboard()#打开剪切板 win32clipboard.EmptyClipboard()#设置剪切板为空,赋初始值是程序员的好习惯,注意一开始的样子 win32clipboard.SetClipboardText(send_message, win32clipboard.CF_TEXT) print("设置剪切板的返回值是:{}".format(win32clipboard.SetClipboardText(send_message, win32clipboard.CF_TEXT))) #SetClipboardText的2个参数解读 #send_message ->文本:str / unicode 要放置在剪贴板上的文本。 #win32clipboard.CF_TEXT ->格式 = CF_TEXT: 要使用的剪贴板格式 - 必须是CF_TEXT或CF_UNICODETEXT getResult= win32clipboard.GetClipboardData(win32clipboard.CF_TEXT).decode('GBK')#获取剪切板数据并转码 win32clipboard.CloseClipboard()#关闭剪切板,有始有终,关闭以此减少资源占用 print("获取到剪切板内容是:{}".format(getResult)) except Exception as e: print("错误:{}".format(e)) ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/3ed5ebef6be2429699c40fba6c980976.png)
### 10. 消息框与选择问答 > #弹出一个消息框,并要求反馈 > 原型:win32api.MessageBox(窗口句柄, "消息内容", "消息标题", 选项个数标记) > 选项个数标记对应关系: 标记0表示一个选项,标记1表示2个选项,标记2表示3个选项 > 实例:result = win32api.MessageBox(handle, "消息内容", "消息标题", 1) > 返回值:选择了第几个选项,从左到右,从1开始计数 ```python import win32api import win32gui # 注意窗口句柄获取如果失败,要做好异常处理 try: # 获取窗口句柄 handle = win32gui.FindWindowEx(0, 0, "Notepad", None)#桌面窗口的所有子窗口检索类名"Edit",标题为None的窗口 print("窗口句柄是:{}".format(handle)) result = win32api.MessageBox(handle, "消息内容", "消息标题", 1)#win32con.MB_OK和0是一样的 表示一个选项,1表示有两个选项,2表示有三个选项 print(result)#返回1表示选择第一个选项,返回2表示选择第二个选项 if result==1: win32api.MessageBox(handle, "我猜对了吗?", "我猜你你选了第1个选项", 0) elif result==2: win32api.MessageBox(handle, "我猜对了吗?", "我猜你你选了第2个选项", 0) except Exception as e: print("窗口句柄获取失败或是前台设置失败:{}".format(e)) ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/b07fc5ab82d745d49b68c4e3af8b40ed.gif)
### 11. 关闭窗口 > #关闭窗口 > 原型:win32gui.PostMessage(handle, 对窗口发送的消息命令, 0, 0) > 实例:win32gui.PostMessage(handle, win32con.WM_CLOSE, 0, 0) > 返回值:None ```python import win32api import win32con import win32gui # 注意窗口句柄获取如果失败,要做好异常处理 try: # 获取窗口句柄 handle = win32gui.FindWindowEx(0, 0, "Notepad", None)#桌面窗口的所有子窗口检索类名"Edit",标题为None的窗口 print("窗口句柄是:{}".format(handle)) result=win32api.MessageBox(handle, "我要关闭句柄为{}的窗口了".format(handle), "关闭窗口警告", 1) if result == 1: win32api.MessageBox(handle, "关闭窗口了", "关闭窗口", 0) win32gui.PostMessage(handle, win32con.WM_CLOSE, 0, 0)#关闭窗口 elif result == 2: win32api.MessageBox(handle, "看来你不想关闭窗口啊", "不关闭窗口", 0) except Exception as e: print("窗口句柄获取失败或是前台设置失败:{}".format(e)) ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/b1ff3ac0dfb64b98872c9c009056f1d3.gif)
### N. 小结 - 为了更好的模拟人类正常的操作,其实还需要对于官方原生函数进行这样那样的封装改良。(有些情景有反机器人机制),比如鼠标按下弹起之间有一个随机的延时,比如鼠标点击有一个随机的抖动,按下后随机偏移几个像素点坐标然后再弹起,后面会讲讲这些内容的封装。 - 其实键鼠的操作可以用到python的另一个库`pynput`会更加方便。 - 专栏后面的文章也会讲解`pynput`。 - 未完待续,持续更新(评论区留言)
## 总结 大家喜欢的话,给个👍,点个关注!给大家分享更多有趣好玩的python自动化办公知识! **版权声明:** 发现你走远了@mzh原创作品,转载必须标注原文链接 Copyright 2022 mzh Crated:2022-8-1 > **欢迎关注 [『python自动化』 系列](https://blog.csdn.net/u011027547/category_11976162.html),持续更新中** > **欢迎关注 [『python自动化』 系列](https://blog.csdn.net/u011027547/category_11976162.html),持续更新中** > [【python自动化】01.安装配置库和环境之win32gui安装失败(保姆级图文)](https://blog.csdn.net/u011027547/article/details/126450109) > 【更多内容敬请期待】