document
利用Python和win32编程范例按需定制一个按键精灵
SendMessage 用法详解及消息详解
用pywin32实现windows模拟鼠标及键盘动作
PyWin32 Documentation
SetForegroundWindow的正确用法
WinAPI: FindWindow、FindWindowEx - 查找窗口
通过ctypes的windll,user32实现调用win32api
python打包方法
在中文windows下使用pywinauto进行窗口操作(一)
notepad保存,指定文件名和文件路径
# coding=utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import os
import time
import win32gui
import win32api
import win32con
def find_idxSubHandle(pHandle, winClass, index=0):
"""已知子窗口的窗体类名 寻找第index号个同类型的兄弟窗口"""
assert type(index) == int and index >= 0
handle = win32gui.FindWindowEx(pHandle, 0, winClass, None)
while index > 0:
handle = win32gui.FindWindowEx(pHandle, handle, winClass, None)
index -= 1
return handle
def find_subHandle(pHandle, winClassList):
"""
递归寻找子窗口的句柄
pHandle是祖父窗口的句柄
winClassList是各个子窗口的class列表,父辈的list-index小于子辈
"""
assert type(winClassList) == list
if len(winClassList) == 1:
return find_idxSubHandle(pHandle, winClassList[0][0], winClassList[0][1])
else:
pHandle = find_idxSubHandle(pHandle, winClassList[0][0], winClassList[0][1])
return find_subHandle(pHandle, winClassList[1:])
def p_sub_handle(phandle):
"""输出phandle的所有子控件"""
handle = -1
while handle !=0 :
if handle == -1:
handle = 0
handle = win32gui.FindWindowEx(phandle, handle, None, None)
if handle != 0:
print win32gui.GetClassName(handle)
hd_notepad = win32gui.FindWindow("notepad", None)
print win32gui.GetWindowText(hd_notepad)
#输出notepad的窗口名称
hd_menu = win32gui.GetMenu(hd_notepad)
hd_submenu = win32gui.GetSubMenu(hd_menu, 0)
#第一个子菜单
hd_menuid = win32gui.GetMenuItemID(hd_submenu, 2)
#从0开始,所以保存是第3个
win32gui.PostMessage(hd_notepad, win32con.WM_COMMAND, hd_menuid, 0)
#win32gui.SendMessage(hd_notepad, win32con.WM_COMMAND, hd_menuid, 0)
win32api.Sleep(200)
#必须有时间间隔,否则无法获得handle
dig_handle = win32gui.FindWindow(None, u"另存为")
print win32gui.GetWindowText(dig_handle)
con_button_handle = win32gui.FindWindowEx(dig_handle, 0, "Button", None)
print win32gui.GetWindowText(con_button_handle)
#handle = find_subHandle(dig_handle, [("WorkerW", 0), ("ReBarWindow32", 0), ("Address Band Root", 0), ("msctls_progress32", 0), ("ComboBoxEx32",0), ("ComboBox", 0), ("Edit", 0)])
handle = find_subHandle(dig_handle, [("WorkerW", 0), ("ReBarWindow32", 0), ("Address Band Root", 0), ("msctls_progress32", 0)])
#没有激活,但是手动鼠标单击地址栏则激活成功
# win32gui.SendMessage(handle, win32con.WM_LBUTTONDOWN, 0, 0)
# win32api.Sleep(200)
# win32gui.SendMessage(handle, win32con.WM_LBUTTONUP, 0, 0)
#自动模拟激活失败
handle = find_subHandle(dig_handle, [("DUIViewWndClassName", 0), ("DirectUIHWND", 0), ("FloatNotifySink", 0), ("ComboBox", 0), ("Edit", 0)])
#当前handle为文件名
win32gui.SetForegroundWindow(handle)
#另存为窗口置顶
win32gui.SendMessage(handle, win32con.WM_LBUTTONDOWN, 0, 0)
win32api.Sleep(200)
win32gui.SendMessage(handle, win32con.WM_LBUTTONUP, 0, 0)
win32api.Sleep(200)
fgFilePath = "d:/1"
print win32gui.GetWindowText(handle)
print handle
print win32api.SendMessage(handle, win32con.WM_SETTEXT, 0, os.path.abspath(fgFilePath))
#第一次打开另存为,不能输入文件名,重新运行程序则输入成功
#如果类名不能获取窗口句柄,文件名不能完整找到,可以枚举窗口,需找符合条件的窗口。
def findPicPick():
hd_list = []
#回调函数
def foo(hwnd, mouse):
# 去掉下面这句会使所有窗口都输出
if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
#注意大写
#print win32gui.GetWindowText(hwnd)
if "PicPick" in win32gui.GetWindowText(hwnd):
hd_list.append(hwnd)
win32gui.EnumWindows(foo, 0)
#hd_notepad = win32gui.FindWindow("notepad", None) 成功
#hd2 = win32gui.FindWindow(None, "TfrmMDIEditor") 失败,找不到picpcik
#print hd_notepad
#print hd2
win32api.keybd_event(18,0,0,0) # Alt
win32api.keybd_event(18, 0, win32con.KEYEVENTF_KEYUP, 0)
win32api.keybd_event(70,0,0,0) # F
win32api.keybd_event(70, 0, win32con.KEYEVENTF_KEYUP, 0)
handle = win32gui.FindWindowEx(phandle, handle, None, None)
寻找pHandle的子控件,在handle之后的第一个子控件,None 分别是类名和title。
hd_notepad = win32gui.FindWindow("notepad", None)
找到类名”notepad“, title = None 的窗口句柄
win32gui.GetClassName(handle)
win32gui.GetWindowText(hd_notepad)
win32api.Sleep(200)
win32gui.SetForegroundWindow(handle)
win32gui.EnumWindows(foo, 0)
win32api.keybd_event(18,0,0,0) # Alt
win32gui.PostMessage(hd_notepad, win32con.WM_COMMAND, hd_menuid, 0)
win32gui.SendMessage(hd_notepad, win32con.WM_COMMAND, hd_menuid, 0)
post 没有返回值,执行完马上返回。
send 返回执行结果,需要等程序执行完成返回。