【问题标题】:Return the foreground window from two windows从两个窗口返回前景窗口
【发布时间】:2020-10-04 05:05:44
【问题描述】:

win32编程中,给定两个重叠的窗口w1w2,如何获取前景窗口?

【问题讨论】:

    标签: c++ windows qt winapi


    【解决方案1】:

    GetForegroundWindow() 为您提供实际 前景窗口(具有当前焦点的窗口)。前台一次只能有 1 个窗口。

    如果您的 2 个窗口都不是前景窗口,则没有可用的 API 直接确定哪个窗口在 z 顺序上高于另一个窗口。您必须手动确定,通过使用EnumWindows()EnumChildWindows() 枚举窗口。窗口根据其 z 顺序进行枚举。

    例如:

    struct myEnumInfo
    {
        HWND hwnd1;
        HWND hwnd2;
        HWND hwndOnTop;
    };
    
    BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
    {
        myEnumInfo *info = (myEnumInfo*) lParam;
    
        // is one of the HWNDs found?  If so, return it...
        if ((hwnd == info->hwnd1) || (hwnd == info->hwnd2))
        {
            info->hwndOnTop = hwnd;
            return FALSE; // stop enumerating
        }
    
        return TRUE; // continue enumerating
    }
    
    BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
    {
        myEnumInfo *info = (myEnumInfo*) lParam;
    
        // is one of the HWNDs found?  If so, return it...
        if ((hwnd == info->hwnd1) || (hwnd == info->hwnd2))
        {
            info->hwndOnTop = hwnd;
            return FALSE;
        }
    
        // enumerate this window's children...
        EnumChildWindows(hwnd, &EnumChildProc, lParam);
    
        // is one of the HWNDs found?  If so, return it...
        if (info->hwndOnTop)
            return FALSE; // stop enumerating
    
        return TRUE; // continue enumerating
    }
    
    HWND WhichOneIsOnTop(HWND hwnd1, HWND hwnd2)
    {
        // is one of the HWNDs null? If so, return the other HWND...
        if (!hwnd1) return hwnd2;
        if (!hwnd2) return hwnd1;
    
        // is one of the HWNDs in the actual foreground? If so, return it...
        HWND fgWnd = GetForegroundWindow();
        if ((fgWnd) && ((fgWnd == hwnd1) || (fgWnd == hwnd2)))
            return fgWnd;
    
        myEnumInfo info;
        info.hwnd1 = hwnd1;
        info.hwnd1 = hwnd2;
        info.hwndOnTop = NULL;
    
        // are the HWNDs both children of the same parent?
        // If so, enumerate just that parent...
        HWND parent = GetAncestor(hwnd1, GA_PARENT);
        if ((parent) && (GetAncestor(hwnd2, GA_PARENT) == parent))
        {
            EnumChildWindows(parent, &EnumChildProc, (LPARAM)&info);
        }
        else
        {
            // last resort!! Enumerate all top-level windows and their children,
            // looking for the HWNDs wherever they are...
            EnumWindows(&EnumWindowsProc, (LPARAM)&info);
        }
    
        return info.hwndOnTop;
    }
    

    【讨论】:

    • foreground windowZ order 是不同的概念。事实上,“一个最顶层窗口会覆盖所有其他非最顶层窗口,无论它是活动窗口还是前景窗口。”
    • @IInspectable 我修好了
    • 当我使用EnumWindows() 时,它会返回许多不可见的窗口(例如,我有一个打开的窗口,它会返回许多窗口),即使我使用IsWindowVisibleIsIconic 来删除不可见的窗口。我应该怎么做才能在我的桌面上打开窗口?
    • @Feiying 忽略您不感兴趣的窗口。您有 2 个 HWND,只需将它们传递给您的枚举回调,并返回找到的第一个 HWND。
    • 如何确认传入我的回调函数的第一个 HWND 是我想要的?例如,我打开了 1 个窗口,enumWindows() 将 5 个窗口 HWND 传递给我的回调函数。我应该怎么做才能过滤这些 HWND?我尝试使用IsWindowVisible()IsIconic(),但它仍然有很多窗口。
    猜你喜欢
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多