一招讓Windows FindWindow函數更好用


  我們通過python來開發自動化或者RPA工具時,經常需要用到大名鼎鼎的pywin32庫。里面有諸如sendMessage、PostMessage、FindWindow、FindwindowEx、EnumWindows等大票好用的windows系統API函數。提到Findow函數,就不得不提及它的一大缺憾:不支持基於窗口標題關鍵字模糊查找

  我們先來認識下今天的主角FindWindow函數。

  MSDN中的解釋如下:

 

 

   簡單地說,該函數檢索處理頂級窗口的類名和窗口名稱匹配指定的字符串,並不會搜索子窗口。

它的C++參數構成如下:

HWND FindWindowA(
  [in, optional] LPCSTR lpClassName,
  [in, optional] LPCSTR lpWindowName
);

  再來看下它的返回值:

 

 

   如果函數執行成功,它會返回包含指定類名和窗口名的窗口對應的句柄,如果失敗,則返回Null。

 

  認識了該函數之后,我們再回到文章開頭提到的痛點,如何讓該函數支持基於窗口標題模糊查找呢?

  大體的思路是,利用EnumWindows函數得到所有頂級窗口的句柄,再通過GetClassName、GetWindowText等函數依次拿到對應窗口的類名、標題,並與我們預設的類名、窗口名關鍵字進行匹配,如果能關聯到,返回對應的窗口句柄即可,我們需要的是這樣一個人性化的FindWindow函數,姑且取名find_window_wildcard,說干就干,下面是具體的實現過程。

 1 import win32gui,re
 2 class WindowMgr:
 3     """Encapsulates some calls to the winapi for window management"""
 4 
 5     def __init__ (self):
 6         """Constructor"""
 7         self._handle = None
 8 
 9     def find_window(self, class_name, window_name=None):
10         """基於類名來查找窗口"""
11         self._handle = win32gui.FindWindow(class_name, window_name)
12 
13     def _window_enum_callback(self, hwnd, class_name_wildcard_list):
14         """傳遞給win32gui.EnumWindows(),檢查所有打開的頂級窗口"""
15         class_name,wildcard=class_name_wildcard_list
16         if win32gui.GetClassName(hwnd)==class_name and re.match(wildcard, str(win32gui.GetWindowText(hwnd))) is not None:
17             self._handle = hwnd
18 
19     def find_window_wildcard(self, class_name,wildcard):
20         """根據類名,查找一個頂級窗口,確保其類名相符,且標題可以用正則表達式匹配對應的通配符"""
21         self._handle = None
22         win32gui.EnumWindows(self._window_enum_callback,[class_name, wildcard])
23         return self._handle
24 
25     def set_foreground(self):
26         """put the window in the foreground"""
27         win32gui.SetForegroundWindow(self._handle)
28 
29     def get_hwnd(self):
30         """return hwnd for further use"""
31         return self._handle
32 if __name__=="__main__":
33     myWindowMgr=WindowMgr()
34     '''查找一個類名為XLMAIN,窗口標題中含【銀行余額】字符串的窗口,並返回它的句柄;如果沒找到,返回None'''
35     excelHwnd=myWindowMgr.find_window_wildcard("XLMAIN",".*?銀行余額.*?")
36     print(excelHwnd)

各位筒子趕緊試試,試完你一定會回來感謝我的,相信我~~

快來掃碼關注我的公眾號 獲取更多爬蟲、數據分析的知識!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM