目录
一.获取窗口句柄
1.根据类名、标题获取窗口句柄
FindWindow
FindWindowEx
2.根据坐标获取窗口句柄
WindowFromPoint
ChildWindowFromPoint
3.获取当前活动窗口(前台)句柄
4.获取具有焦点的窗口的句柄
5.枚举窗口句柄:顶层窗口句柄、子窗口句柄
EnumWindows:枚举顶层窗口句柄
EnumChildWindows:枚举指定父窗口的字窗口句柄
二.窗口操作
1.判断窗口是否存在、可见、最小化
2.获取窗口位置、尺寸信息、标题
3.设置窗口标题
4.显示或隐藏窗口
5.设置窗口焦点
6.窗口置顶(输入焦点)-前台窗口
7.窗口置顶(不改变输入焦点)
8.设置窗口位置、大小、z顺序
win32gui.SetWindowPos(hwnd%2C%20hWndInsertAfter%2C%20x%2C%20y%2C%20cx%2C%20cy%2C%20wFlags)-toc" style="margin-left:160px;">win32gui.SetWindowPos(hwnd, hWndInsertAfter, x, y, cx, cy, wFlags)
win32gui.MoveWindow(hwnd%2C%20x%2C%20y%2C%20nWidth%2C%20nHeight%2C%20bRepaint)-toc" style="margin-left:160px;">win32gui.MoveWindow(hwnd, x, y, nWidth, nHeight, bRepaint)
9.获取窗口的某个属性值
GetWindowLong
10.窗口闪烁
FlashWindow
11.坐标转换
将屏幕坐标转换为客户端坐标
将客户端坐标转换为屏幕坐标
三.向窗口发送消息
SendMessage
PostMessage
发送消息示例
1.关闭窗口
2.模拟按键输入
3.后台输入文字
4.模拟鼠标后台单击、双击
5.模拟鼠标移动
四.窗口绘制图形
一.获取窗口句柄
1.根据类名、标题获取窗口句柄
FindWindow
- 参数:
className
:窗口的类名title
:窗口的标题
- 功能:用于查找与指定窗口类名和窗口名称相匹配的顶级窗口。不搜索子窗口,并且不区分大小写。如果找不到匹配的窗口,返回0。
python">#标题和类名其中一个可以为None
hwnd=win32gui.FindWindow(className,title)#若匹配到,则返回顶层窗口的句柄,否则返回0
FindWindowEx
- 参数:
hwndParent
:父窗口的句柄。如果为0,则以桌面窗口为父窗口。hwndChildAfter
:子窗口句柄。如果为0,则从第一个子窗口开始查找。className
:窗口的类名。title
:窗口的标题
- 功能:用于在窗口列表中寻找与指定条件相符的子窗口。它搜索子窗口,并且从排在给定的子窗口后面的下一个子窗口开始查找。如果不设置
hwndParent
,则从桌面窗口开始查找所有子窗口。
python">#相对于桌面窗口,其他窗口都是桌面窗口的子窗口
#查找子窗口
hwnd=win32gui.FinWindow(0,0,'title','className')#标题和类名,其中一个参数可以为None
#查找指定窗口(父窗口)的子窗口
hwnd=win32gui.FinWindow(pHwnd,0,'title','className')
#查找指定父窗口)以及子窗口的下一级子窗口
hwnd=win32gui.FinWindow(pHwnd,cHwnd,'title','className')
2.根据坐标获取窗口句柄
WindowFromPoint
- 参数:
point
:tuple数据类型,(x,y)为相对于屏幕窗口位置的坐标。
- 功能:用于获取屏幕上特定点的顶级窗口句柄
python">hwnd = win32gui.WindowFromPoint((x,y))
ChildWindowFromPoint
- 参数:
hwndParent
:父窗口的句柄。point
:tuple数据类型,(x,y)为相对于父窗口的坐标。
- 功能:获取屏幕上特定点的子窗口句柄
python">hwnd = win32gui.ChildWindowFromPoint(pHwnd(x,y))
3.获取当前活动窗口(前台)句柄
python">hwnd = win32gui.GetForegroundWindow()
4.获取具有焦点的窗口的句柄
python">hwnd=win32gui.GetFocus()
5.枚举窗口句柄:顶层窗口句柄、子窗口句柄
EnumWindows:枚举顶层窗口句柄
- 参数:
callback
:回调函数。回调函数接收两个参数:一个窗口句柄(HWND)和一个传递给EnumWindows
的应用程序定义值。对于每个顶级窗口,系统都会调用这个回调函数,直到回调函数返回False
或者所有的窗口都被枚举完毕- extra:可选的参数。通常用于传递数据到回调函数。可选参数对于
EnumWindows
函数本身并不直接使用,但它可以被用作一种方式,将额外的数据或状态传递给回调函数。
- extra:
-
传递数据:可以将任何需要的数据作为这个可选参数传递给回调函数。例如,传递一个列表或字典,以便在回调函数中收集或更新数据。
-
状态共享:如果需要在多个回调函数之间共享状态(比如计数或标志),可以创建一个可变对象(如列表或字典),并将其作为可选参数传递。这样,回调函数就可以修改这个对象,并且这些修改在后续的回调中可见。
-
控制枚举:可以使用这个参数来控制枚举的过程。例如,可以在回调函数中检查某个条件,如果满足,则通过修改这个参数来通知
EnumWindows
停止枚举。
-
- 功能:枚举所有顶级窗口
python">hwndList=[]
win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hwndList)#枚举完所有的顶级窗口后结束运行hwndList=[]
def callback(hwnd,title):if hwnd='xxx':return FalsetitleList.append(title)#titleList列表作为可选参数传递给了 EnumWindows。回调函数 callback 将每个窗口的标题添加到这个titleList列表中
win32gui.EnumWindows(callback, titleList)#枚举到句柄为xxx的窗口时,结束运行hwndDict={}
def callback(hwnd,title):#IsWindow:判断指定的窗口是否打开#IsWindowEnabled:判断窗口是否已启用#IsWindowVisible:窗口是否可见if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd):title.update({hwnd: win32gui.GetWindowText(hwnd)})
win32gui.EnumWindows(callback, titleList)#枚举完所有的顶级窗口后结束运行
EnumChildWindows:枚举指定父窗口的字窗口句柄
- 参数:
- hwnd:父窗口句柄;
callback
:回调函数。回调函数接收两个参数:一个窗口句柄(HWND)和一个传递给EnumWindows
的应用程序定义值。对于每个顶级窗口,系统都会调用这个回调函数,直到回调函数返回False
或者所有的窗口都被枚举完毕- extra:可选的参数。通常用于传递数据到回调函数。可选参数对于
EnumWindows
函数本身并不直接使用,但它可以被用作一种方式,将额外的数据或状态传递给回调函数。
- 功能:枚举指定父窗口的子窗口
python">win32gui.EnumChildWindows(pHwnd, lambda hwnd, param: param.append(hwnd), hwndList)#获取父窗口下的所有后代窗口句柄
二.窗口操作
1.判断窗口是否存在、可见、最小化
python">win32gui.IsWindow(hwnd)#窗口是否存在,句柄是否有效
win32gui.IsWindowVisible(hwnd)#窗口是否可见
win32gui.IsIconic(hwnd)#窗口是否最小化
2.获取窗口位置、尺寸信息、标题
python">rect = win32gui.GetWindowRect(hwnd)
left, top, width, height = rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]title=win32gui.GetWindowText(hwnd)
3.设置窗口标题
python">win32gui.SetWindowText(hwnd, new_title)
4.显示或隐藏窗口
python">win32gui.ShowWindow(hwnd,win32con.SW_HIDE)#隐藏
win32gui.ShowWindow(hwnd,win32con.SW_SHOW)#显示
5.设置窗口焦点
python">win32gui.SetFocus(hwnd)# 将焦点设置到该窗口(或控件)上
6.窗口置顶(输入焦点)-前台窗口
python">win32gui.SetForegroundWindow(hwnd)#窗口置顶
7.窗口置顶(不改变输入焦点)
python">win32gui.BringWindowToTop(hwnd)
8.设置窗口位置、大小、z顺序
win32gui.SetWindowPos(hwnd%2C%20hWndInsertAfter%2C%20x%2C%20y%2C%20cx%2C%20cy%2C%20wFlags)">win32gui.SetWindowPos(hwnd, hWndInsertAfter, x, y, cx, cy, wFlags)
- 参数:
hwnd
:窗口句柄。hWndInsertAfter
:指定窗口 Z 顺序的位置。这可以是一个窗口句柄,表示将hwnd
置于该窗口之后;也可以是特殊的值,如win32con.HWND_TOP
(将窗口置于所有其他窗口之上)、win32con.HWND_BOTTOM
(将窗口置于所有其他窗口之下)等。x
和y
:指定窗口新位置的左上角的 x 和 y 坐标。这些坐标是相对于屏幕左上角的,除非wFlags
指定了其他坐标系。cx
和cy
:指定窗口的新宽度和高度(以像素为单位)。wFlags
:一组标志,用于指定窗口大小和位置的各种选项。例如,win32con.SWP_NOMOVE
保持窗口位置不变,win32con.SWP_NOSIZE
保持窗口大小不变,win32con.SWP_SHOWWINDOW
显示窗口等。
wFlags
:- 功能:移动窗口到屏幕上的特定位置、改变一个窗口的大小以适应其内容、控制窗口的堆叠顺序、显示或隐藏窗口等
python"># 设置窗口的位置和大小
# 将窗口置于所有其他窗口之上,并移动到屏幕左上角,大小为 800x600
win32gui.SetWindowPos(hwnd, win32con.HWND_TOP, 0, 0, 800, 600, win32con.SWP_SHOWWINDOW)
win32gui.MoveWindow(hwnd%2C%20x%2C%20y%2C%20nWidth%2C%20nHeight%2C%20bRepaint)">win32gui.MoveWindow(hwnd, x, y, nWidth, nHeight, bRepaint)
- 参数:
hwnd
:要移动和调整大小的窗口的句柄。x
和y
:指定窗口新位置的左上角的 x 和 y 坐标。这些坐标是相对于屏幕左上角的。nWidth
和nHeight
:指定窗口的新宽度和高度(以像素为单位)。bRepaint
:一个布尔值,指定是否要重绘窗口。如果为True
,则窗口在移动或调整大小后将被重绘;如果为False
,则不会重绘。
- 功能:类似于SetWindowPos移动和调整窗口的大小,但不涉及窗口的 Z 顺序或其他高级选项
python"># 移动窗口到屏幕上的 (100, 100) 位置,并将其大小调整为 800x600 像素
win32gui.MoveWindow(hwnd, 100, 100, 800, 600, True)
9.获取窗口的某个属性值
GetWindowLong
- 功能:用于获取指定窗口的某个属性的值。这些属性可以控制窗口的许多方面,如样式、扩展样式、窗口过程等。
- 参数:
- 常用的窗口属性索引:
- 返回值:返回指定属性的值。该值是一个整数,其含义取决于所请求的属性
python"># 获取窗口的样式属性
style = win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE)
10.窗口闪烁
FlashWindow
- 参数:
hwnd
:要闪烁的窗口的句柄。- bInvert:布尔值,指定是否反转窗口的颜色。如果为
True
,窗口会反转其颜色(通常是从白色变为黑色,或从当前颜色变为其反色)并再次反转回来,产生闪烁效果。如果为False
,则窗口不会反转颜色,但仍然会在任务栏中闪烁。 wParam
: 消息的第一个参数。其含义取决于具体的消息编号。lParam
: 消息的第二个参数。其含义也取决于具体的消息编号。
- 功能:用于使一个窗口在任务栏中闪烁,以提醒用户注意。这个函数通常用于当应用程序需要用户注意时,比如有新消息到达或者某个任务完成。
python">win32gui.FlashWindow(hwnd,True)
11.坐标转换
将屏幕坐标转换为客户端坐标
python">(int,int) = win32gui.ScreenToClient(hWnd,(x,y))(int,int)=(x-winX,y-winY)#winX,winY:窗口坐标(相对于屏幕)
将客户端坐标转换为屏幕坐标
python">(int,int) = win32gui.ClientToScreen(hWnd,(x,y))(int,int)=(winX+x,winY+y)#winX,winY:窗口坐标(相对于屏幕)
三.向窗口发送消息
SendMessage
- 参数:
- 常见消息常量:
win32con.WM_CLOSE
:请求关闭一个窗口。当窗口接收到此消息时,通常会触发关闭操作。win32con.WM_DESTROY
:一个窗口正在被销毁。此消息在窗口被销毁之前发送。win32con.WM_PAINT
:请求重绘窗口的客户区。当窗口的内容需要更新时,系统会发送此消息。win32con.WM_SETTEXT
:设置窗口的标题或文本。lParam
参数应指向包含新文本的字符串。win32con.WM_GETTEXT
:获取窗口的标题或文本。lParam
参数应指向接收文本的缓冲区,wParam
参数指定缓冲区的大小。win32con.WM_COMMAND
:用户选择了一个菜单项、点击了一个按钮或其他命令控件。wParam
参数的高位字(HIWORD)通常是控件的标识符,低位字(LOWORD)是通知码。WM_KEYDOWN
:按下键盘按键的消息。WM_KEYUP
:释放键盘按键的消息。WM_LBUTTONDOWN
:鼠标左键按下。WM_LBUTTONUP
:鼠标左键释放。WM_MOUSEMOVE
:鼠标移动。WM_PAINT
:窗口需要重绘
- 功能:用于向指定的窗口发送消息。
SendMessage
是一个同步操作,它会等待消息被处理后才返回。这意味着如果你的消息处理函数执行了长时间的操作,SendMessage
也会相应地阻塞。
PostMessage
- 参数、功能:与SendMessage相同
win32gui.PostMessage
是进行异步消息发送的有用工具,不需要等待消息处理结果时。
发送消息示例
1.关闭窗口
python"># 发送 WM_CLOSE 消息来请求关闭窗口
win32gui.PostMessage(hWnd, win32con.WM_CLOSE, 0, 0)
2.模拟按键输入
python">def backstageKBD(keyLists,hwnd):#keyLists:['A','B'],大写keyMap = { "0": 49, "1": 50, "2": 51, "3": 52, "4": 53, "5": 54, "6": 55, "7": 56, "8": 57, "9": 58,'F1': 112, 'F2': 113, 'F3': 114, 'F4': 115, 'F5': 116, 'F6': 117, 'F7': 118, 'F8': 119,'F9': 120, 'F10': 121, 'F11': 122, 'F12': 123, 'F13': 124, 'F14': 125, 'F15': 126, 'F16': 127, "A": 65, "B": 66, "C": 67, "D": 68, "E": 69, "F": 70, "G": 71, "H": 72, "I": 73, "J": 74,"K": 75, "L": 76, "M": 77, "N": 78, "O": 79, "P": 80, "Q": 81, "R": 82, "S": 83, "T": 84,"U": 85, "V": 86, "W": 87, "X": 88, "Y": 89, "Z": 90,'BACKSPACE': 8, 'TAB': 9, 'TABLE': 9, 'CLEAR': 12,'ENTER': 13, 'SHIFT': 16, 'CTRL': 17,'CONTROL': 17, 'ALT': 18, 'ALTER': 18, 'PAUSE': 19, 'BREAK': 19, 'CAPSLK': 20, 'CAPSLOCK': 20, 'ESC': 27,'SPACE': 32, 'SPACEBAR': 32, 'PGUP': 33, 'PAGEUP': 33, 'PGDN': 34, 'PAGEDOWN': 34, 'END': 35, 'HOME': 36,'LEFT': 37, 'UP': 38, 'RIGHT': 39, 'DOWN': 40, 'SELECT': 41, 'PRTSC': 42, 'PRINTSCREEN': 42, 'SYSRQ': 42,'SYSTEMREQUEST': 42, 'EXECUTE': 43, 'SNAPSHOT': 44, 'INSERT': 45, 'DELETE': 46, 'HELP': 47, 'WIN': 91,'WINDOWS': 91, 'NMLK': 144,'NUMLK': 144, 'NUMLOCK': 144, 'SCRLK': 145}#指定的窗口设置为前台窗口,即当前活动窗口win32gui.SetForegroundWindow(hwnd)#模拟按键:输入一个键或组合键for key in keyLists:#按下win32api.keybd_event(keyMap[key], 0, 0, 0)#win32gui.PostMessage(hwnd, win32con.WM_KEYDOWN, keyMap[key], 0)time.sleep(0.05)for key in keyLists[::-1]:#松开win32api.keybd_event(keyMap[key],0, win32con.KEYEVENTF_KEYUP, 0)#win32gui.PostMessage(hwnd, win32con.WM_KEYUP, keyMap[key], 0)
3.后台输入文字
python">#指定的窗口设置为前台窗口,即当前活动窗口
win32gui.SetForegroundWindow(hwnd)
#模拟输入
for item in '哈哈哈':win32api.PostMessage(hwnd, win32con.WM_CHAR, ord(item), 0)
4.模拟鼠标后台单击、双击
python"># 单击、双击,左键,右键
def click(hwnd,x,y,style='click',lr='left'):long_position=win32api.MAKELONG(x, y) # 等价于(y) << 16 | (x) dictLR={'left':[win32con.WM_LBUTTONDOWN,win32con.WM_LBUTTONUP],'right':[win32con.WM_RBUTTONDOWN,win32con.WM_LBUTTONUP]}if style=='click':# 模拟鼠标按下# 相对于句柄窗口坐标win32api.PostMessage(hwnd, dictLR[lr][0], 0, long_position)time.sleep(0.01)# 模拟鼠标弹起win32api.PostMessage(hwnd, dictLR[lr][1], 0, long_position)time.sleep(0.01)elif style=='Double':#双击#先单击选中,在双击# 模拟鼠标按下# 相对于句柄窗口坐标win32api.PostMessage(hwnd, dictLR[lr][0], 0, long_position)time.sleep(0.01)# 模拟鼠标弹起win32api.PostMessage(hwnd, dictLR[lr][1], 0, long_position)time.sleep(0.01)#双击win32api.PostMessage(hwnd, win32con.WM_LBUTTONDBLCLK, win32con.MK_LBUTTON, long_position)# win32api.PostMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, long_position)time.sleep(0.01)#单击
click(hwnd,x,y)
#双击
click(hwnd, x,y, style='Double')
#连击
for f in range(3):self.click(hwnd, x,y)
5.模拟鼠标移动
python"># 发送鼠标移动消息
def move_mouse(x, y):win32gui.PostMessage(win32gui.GetDesktopWindow(), win32con.WM_MOUSEMOVE, 0, win32gui.MAKELONG(x, y))#MAKELONG函数将x和y坐标合并成一个32位的值time.sleep(0.01)#延迟0.01秒,可以模拟连续的鼠标移动操作。for item in [[1,2],[3,4],[5,6]]:move_mouse(item[0], item[1])