使用 EnumWindows 找到知足你要求的窗口
2019-04-30 13:11 html
在 Windows 應用開發中,若是須要操做其餘的窗口,那麼可使用 EnumWindows
這個 API 來枚舉這些窗口。windows
本文介紹使用 EnumWindows
來枚舉並找到本身關心的窗口(如 QQ/TIM 窗口)。api
EnumWindows
你能夠在微軟官網瞭解到 EnumWindows
。app
要在 C# 代碼中使用 EnumWindows
,你須要編寫平臺調用 P/Invoke 代碼。使用我在另外一篇博客中的方法能夠自動生成這樣的平臺調用代碼:函數
我這裏直接貼出來:post
[DllImport("user32.dll")]
public static extern int EnumWindows(WndEnumProc lpEnumFunc, int lParam);
遍歷全部的頂層窗口
官方文檔對此 API 的描述是:ui
Enumerates all top-level windows on the screen by passing the handle to each window, in turn, to an application-defined callback function.url
遍歷屏幕上全部的頂層窗口,而後給回調函數傳入每一個遍歷窗口的句柄。spa
不過,並非全部遍歷的窗口都是頂層窗口,有一些非頂級系統窗口也會遍歷到,詳見:EnumWindows 中的備註節。.net
因此,若是須要遍歷獲得全部窗口的集合,那麼可使用以下代碼:
public static IReadOnlyList<int> EnumWindows()
{
var windowList = new List<int>();
EnumWindows(OnWindowEnum, 0);
return windowList;
bool OnWindowEnum(int hwnd, int lparam)
{
// 可自行加入一些過濾條件。
windowList.Add(hwnd);
return true;
}
}
遍歷具備指定類名或者標題的窗口
咱們須要添加一些能夠用於過濾窗口的 Win32 API。如下是咱們即將用到的兩個:
// 獲取窗口的類名。
[DllImport("user32.dll")]
private static extern int GetClassName(int hWnd, StringBuilder lpString, int nMaxCount);
// 獲取窗口的標題。
[DllImport("user32")]
public static extern int GetWindowText(int hwnd, StringBuilder lptrString, int nMaxCount);
因而根據類名找到窗口的方法:
public static IReadOnlyList<int> FindWindowByClassName(string className)
{
var windowList = new List<int>();
EnumWindows(OnWindowEnum, 0);
return windowList;
bool OnWindowEnum(int hwnd, int lparam)
{
var lpString = new StringBuilder(512);
GetClassName(hwnd, lpString, lpString.Capacity);
if (lpString.ToString().Equals(className, StringComparison.InvariantCultureIgnoreCase))
{
windowList.Add(hwnd);
}
return true;
}
}
使用此方法,咱們能夠傳入 "txguifoundation"
找到 QQ/TIM 的窗口:
var qqHwnd = FindWindowByClassName("txguifoundation");
要獲取窗口的標題,或者把標題做爲過濾條件,則使用 GetWindowText
。
在 QQ/TIM 中,窗口的標題是聊天對方的名字或者羣聊名稱。
var lptrString = new StringBuilder(512);
GetWindowText(hwnd, lptrString, lptrString.Capacity);
參考資料
- EnumWindows function (winuser.h) - Microsoft Docs
- GetClassName function (winuser.h) - Microsoft Docs
本文會常常更新,請閱讀原文: https://blog.walterlv.com/post/find-specific-window-by-enum-windows.html ,以免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。
若是你想持續閱讀個人最新博客,請點擊 RSS 訂閱,或者前往 CSDN 關注個人主頁。
本做品採用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、從新發布,但務必保留文章署名 呂毅 (包含連接: https://blog.walterlv.com ),不得用於商業目的,基於本文修改後的做品務必以相同的許可發佈。若有任何疑問,請 與我聯繫 (walter.lv@qq.com) 。