使用 EnumWindows 找到知足你要求的窗口 - walterlv

原文: 使用 EnumWindows 找到知足你要求的窗口 - walterlv

使用 EnumWindows 找到知足你要求的窗口

2019-04-30 13:11 html

在 Windows 應用開發中,若是須要操做其餘的窗口,那麼可使用 EnumWindows 這個 API 來枚舉這些窗口。windows

本文介紹使用 EnumWindows 來枚舉並找到本身關心的窗口(如 QQ/TIM 窗口)。api


EnumWindows

你能夠在微軟官網瞭解到 EnumWindowsapp

要在 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);

參考資料

本文會常常更新,請閱讀原文: https://blog.walterlv.com/post/find-specific-window-by-enum-windows.html ,以免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。

若是你想持續閱讀個人最新博客,請點擊 RSS 訂閱,或者前往 CSDN 關注個人主頁

知識共享許可協議 本做品採用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、從新發布,但務必保留文章署名 呂毅 (包含連接: https://blog.walterlv.com ),不得用於商業目的,基於本文修改後的做品務必以相同的許可發佈。若有任何疑問,請 與我聯繫 (walter.lv@qq.com)

相關文章
相關標籤/搜索