用pywin32實(shí)現(xiàn)windows模擬鼠標(biāo)及鍵盤動作
WinAPI: FindWindow或颊、FindWindowEx - 查找窗口
通過ctypes的windll,user32實(shí)現(xiàn)調(diào)用win32api
在中文windows下使用pywinauto進(jìn)行窗口操作(一)
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)
#必須有時(shí)間間隔孽锥,否則無法獲得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)])
#沒有激活逮光,但是手動鼠標(biāo)單擊地址欄則激活成功
# 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)])
#當(dāng)前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))
#第一次打開另存為卒落,不能輸入文件名话瞧,重新運(yùn)行程序則輸入成功
#如果類名不能獲取窗口句柄嫩与,文件名不能完整找到,可以枚舉窗口交排,需找符合條件的窗口划滋。
def findPicPick():
hd_list = []
#回調(diào)函數(shù)
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 沒有返回值架专,執(zhí)行完馬上返回同窘。
send 返回執(zhí)行結(jié)果,需要等程序執(zhí)行完成返回部脚。