Python量化交易基礎講堂-自動控制windows桌面

歡迎你們訂閱《Python實戰-構建基於股票的量化交易系統》小冊子,小冊子會陸續推出與小冊內容相關的專欄文章,對涉及到的知識點進行更全面的擴展介紹。python

在使用PC時與PC交互的主要途徑是看屏幕顯示、聽聲音,點擊鼠標和敲鍵盤等等。在自動化辦公的趨勢下,繁瑣的工做可讓程序自動完成。好比自動化測試、自動下單交易等。不少軟件除了能夠GUI方式操做外還能夠用CLI接口操做,不過當一些軟件未提供CLI接口時,咱們應該怎麼辦呢?咱們還能夠用程序控制桌面上的窗口、模擬點擊鼠標或按下鍵盤等動做來釋放本身。chrome

本篇專欄就主要來介紹下如何經過Python自動控制windows桌面。目前市面上股票量化交易框架中所謂的模擬客戶端登錄證券帳號便是基於這個原理。編程

pywin32是一個Python庫,它爲Python提供訪問Windows API的擴展,提供了齊全的windows常量、接口、線程以及COM機制等等,安裝後會自帶一個pythonwin的IDE。windows

打開軟件/文件

好比打開一個谷歌瀏覽器,或者打開一個word文件,以下所示:api

win32api.ShellExecute(1, 'open',
                      r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe',
                      '', '', 1)

win32api.ShellExecute(1, 'open',
                      r'C:\Users\Jay\Desktop\Environment Guider.docx',
                      '', '', 1)

複製代碼

win32api.ShellExecute()的參數主要包括:瀏覽器

  • HWND:指定父窗口句柄bash

  • Operation:指定動做, 譬如"edit","explore","open","find","print","NULL"微信

  • FileName:指定要打開的文件或程序app

  • Parameters:指定打開程序所需參數框架

  • Directory:缺省目錄

  • ShowCmd:打開選項,可選值:

    • SW_HIDE            = 0;  {隱藏窗口,活動狀態給令一個窗口}
    • SW_SHOWNORMAL      = 1;  {用最近的大小和位置顯示窗口, 同時令其進入活動狀態}
    • SW_NORMAL          = 1;  {用當前的大小和位置顯示一個窗口,不改變活動窗口}
    • SW_SHOWMINIMIZED  = 2;  {最小化窗口,並將其激活}
    • SW_SHOWMAXIMIZED  = 3;  {最大化窗口,並將其激活}
    • SW_MAXIMIZE        = 3;  {同 SW_SHOWMAXIMIZED}
    • SW_SHOWNOACTIVATE  = 4;  {用最近的大小和位置顯示一個窗口,不改變活動窗口}
    • SW_SHOW            = 5;  {用當前的大小和位置顯示一個窗口,令其進入活動狀態}
    • SW_MINIMIZE        = 6;  {最小化窗口, 不激活}
    • SW_SHOWMINNOACTIVE = 7;  {同 SW_MINIMIZE}
    • SW_SHOWNA          = 8;  {用當前的大小和位置顯示一個窗口,不改變活動窗口}
    • SW_RESTORE        = 9;  {同 SW_SHOWNORMAL}
    • SW_SHOWDEFAULT    = 10; {同 SW_SHOWNORMAL}
    • SW_MAX            = 10; {同 SW_SHOWNORMAL}`

執行成功會返回應用程序句柄(該句柄與win32gui.FindWindow()返回的並不相同), 若是返回值 <= 32,則表示執行錯誤。返回值可能的錯誤有:

  • = 0  {內存不足}
  • ERROR_FILE_NOT_FOUND  = 2;  {文件名錯誤}
  • ERROR_PATH_NOT_FOUND  = 3;  {路徑名錯誤}
  • ERROR_BAD_FORMAT      = 11; {EXE 文件無效}
  • SE_ERR_SHARE          = 26; {發生共享錯誤}
  • SE_ERR_ASSOCINCOMPLETE = 27; {文件名不徹底或無效}
  • SE_ERR_DDETIMEOUT      = 28; {超時}
  • SE_ERR_DDEFAIL        = 29; {DDE 事務失敗}
  • SE_ERR_DDEBUSY        = 30; {正在處理其餘 DDE 事務而不能完成該 DDE 事務}
  • SE_ERR_NOASSOC        = 31; {沒有相關聯的應用程序}

查找窗體的句柄

在win32編程的世界裏,包括窗口到文本框的全部控件都是窗體,全部的窗體都有獨立的句柄。要操做任意一個窗體,都須要找到這個窗體的句柄。句柄是一個32位整數,在windows中用於標記對象。好比查找Snipping Tool和New Text Document.txt的句柄,以下所示:

para_hld = win32gui.FindWindow(None, "Snipping Tool")# 1836416

para_hld = win32gui.FindWindow(None, "New Text Document.txt - Notepad")# 591410

複製代碼

win32gui.FindWindow()屬於win32gui的模塊,它自頂層窗口(也就是桌面)開始搜索條件匹配的窗體,並返回這個窗體的句柄。

該函數僅能查找主窗口,所以沒法搜索子窗口,也不區分大小寫,未找到則返回0。 win32gui.FindWindow()的參數主要包括 (lpClassName=None, lpWindowName=None):

  • lpClassName:字符型,窗體的類名,能夠在Spy++裏找到
  • lpWindowName:字符型,窗口名,也就是標題欄上能看見的那個標題。

查找句柄的類名和標題

好比經過Snipping Tool和New Text Document.txt的句柄查找對應的類名和標題,以下所示:

title = win32gui.GetWindowText(1836416)
classname = win32gui.GetClassName(1836416)
print "windows handler:{0}; title:{1}; classname:{2}".format(1836416, title, classname)
打印顯示以下:
windows handler:1836416; title:Snipping Tool; classname:Microsoft-Windows-Tablet-SnipperToolbar


title = win32gui.GetWindowText(591410)
classname = win32gui.GetClassName(591410)
print "windows handler:{0}; title:{1}; classname:{2}".format(591410, title, classname)
打印顯示以下:
windows handler:591410; title:New Text Document.txt - Notepad; classname:Notepad

複製代碼

枚舉窗口句柄

調用win32gui.EnumWindows()枚舉全部窗口句柄,直到最後一個頂層窗口被枚舉則中止枚舉過程。以下所示:

hWndList = []
win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWndList)
print hWndList
for hwnd in hWndList:
    title = win32gui.GetWindowText(hwnd)
    print title
複製代碼

打印顯示以下:

[852802L, 65946L, 65928L, 65930L, 65900L, 65920L, 65924L, 65922L, 65944L, 65892L, 65886L, 6817870L, 65960L, 6031410L, …… 66052L, 65734L]
……
New Text Document.txt - Notepad
Snipping Tool
DDE Server Window
OfficePowerManagerWindow
OfficePowerManagerWindow
DDE Server Window
GDI+ Window
Global Internet Access
……
複製代碼

指定設置最頂層窗口

win32gui.SetForegroundWindow()函數將指定窗體設置到最頂層,而且激活該窗口。構造函數爲:

win32gui.SetWindowPos(HWN hWnd,HWND hWndlnsertAfter, int X,int Y, int cx,int cy, UNIT.Flags)

關於win32gui.SetForegroundWindow(para_hld)報錯的問題:

pywintypes.error: (0, 'SetForegroundWindow', 'No error message is available') 其實調用SetForegroundWindow()會有不少限制,參考官網的說明

更多的量化交易內容歡迎你們訂閱小冊閱讀!!同時也歡迎你們關注個人微信公衆號【元宵大師帶你用Python量化交易】瞭解更多Python量化交易相關內容

相關文章
相關標籤/搜索