Windows窗體數據抓取詳解
最近在客戶項目上剛好遇到一個問題,項目需求是要獲取某台機床的實時狀態,問題點剛好就在於該機床不是傳統意義上的數控機床,也不是PLC控制器,只有一個上傳下載程序文件的應用程序,上面剛好有幾個按鈕可以大概判斷當前工作狀態,轉眼一想,是否可以實時獲取幾個按鈕的狀態,從而簡單分析下就確定機床加工狀態。
說干就干,開始拿起放下已久的Win32API來試試。思路大概如下:
首先,我們知道的是應用程序的進程名稱如:notepad.exe
然後,就要通過進程名獲取窗口句柄(HWND)
其次,通過窗口句柄遍歷子窗口句柄,通過其獲取相關數據,比如:Button是否被可用、Button的Text、CheckButton是否被選中等等一些列想要的操作。此處我們就抓取記事本內容吧(內容在Edit控制項中)
最後,就是實時更新、存儲數據即可,進行後期邏輯處理
獲取進程ID
首先當我們知道進程名,通過進程名獲取進程ID,我們需要用到一個Win32的進程快照模塊:CreateToolhelp32Snapshot可以通過獲取進程信息為指定的進程、進程使用的堆[HEAP]、模塊[MODULE]、線程建立一個快照。
參數:
dwFlags 用來指定「快照」中需要返回的對象,指定快照中包含的系統內容,這個參數能夠使用下列數值(常量)中的一個或多個。
TH32CSINHERIT :聲明快照句柄是可繼承的。
TH32CSSNAPALL :在快照中包含系統中所有的進程和線程。
TH32CSSNAPHEAPLIST : 在快照中包含在th32ProcessID中指定的進程的所有的堆。
TH32CSSNAPMODULE : 在快照中包含在th32ProcessID中指定的進程的所有的模塊。
TH32CSSNAPPROCESS : 在快照中包含系統中所有的進程。
TH32CSSNAPTHREAD :在快照中包含系統中所有的線程。
th32ProcessID 指定將要快照的進程ID。如果該參數為0表示快照當前進程。該參數只有在設置了TH32CSSNAPHEAPLIST或者TH32CSSNAPMODULE後才有效,在其他情況下該參數被忽略,所有的進程都會被快照。
返回值: 調用成功,返回快照的句柄,調用失敗,返回INVALIDHANDLEVALUE 。
廢話不多說,直接上代碼:
調用測試:
獲取到了進程,那就進入下一節,獲取窗口句柄。
獲取窗口句柄HWND
通過進程ID獲取窗口句柄,那麼就需要遍歷窗口了,找到符合我們需求的進程所對應的窗口句柄了,這個地方就會用到一個函數:EnumWindows枚舉所有屏幕上的頂層窗口,並將窗口句柄傳送給應用程序定義的回調函數。
參數:
lpEnumFunc:指向一個應用程序定義的回調函數指針,請參看EnumWindowsProc。
lPararm:指定一個傳遞給回調函數的應用程序定義值。
返回值:如果函數成功,返回值為非零;如果函數失敗,返回值為零。若想獲得更多錯誤信息,請調用GetLastError函數。
回調函數:
參數:
hwnd:頂層窗口的句柄
lparam:應用程序定義的一個值(即EnumWindows中lParam) 返回值:TRUE繼續遍歷,FALSE停止遍歷
註:EnumWindows函數不列舉子窗口。
那麼接下來就是開始獲取窗口句柄了。
首先定一個結構體
該機構體由於標記進程和窗口句柄:
枚舉所有窗口
獲取指定進程ID窗口句柄
調用測試:
結果輸出:
現在已經獲取了記事本主窗口句柄了,下一步就是遍歷子窗口了。
遍歷子窗口
我們的目標是抓取窗體中信息,這時候介紹一個工具,相當的好用Spy++(具體怎麼用,就自己百度了)
現在我們要獲取的就是下面的Edit框內容。此處我們又需要遍歷子窗口,需用到一個方法EnumChildWindows枚舉一個父窗口的所有子窗口。
參數:
hWndParent: 父窗口句柄
lpEnumFunc: 回調函數的地址
lParam: 自定義的參數
回調函數如下:
參數:
hwnd:父窗口指定的一個子窗口句柄
lParam:EnumChidWindows指定的參數 返回值:如果返回TRUE,則枚舉繼續直到枚舉完成;如果返回FALSE,則將會中止枚舉。
直接亮代碼:
調用如下:
結果如下:
到此,就完成既定目標了
TAG:奔跑阿甘 |