Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 获取父窗口的正确方法_Winapi - Fatal编程技术网

Winapi 获取父窗口的正确方法

Winapi 获取父窗口的正确方法,winapi,Winapi,MSDN对GetParent函数作了如下说明: 获取父窗口而不是 所有者不使用GetParent,而是与 GA_父项标志 但是当调用get祖先(hWnd,GA_PARENT)时对于没有父窗口的窗口,它返回桌面窗口,而GetParent返回NULL 那么,获取父对象(而不是所有者)的正确方法是什么?如果没有,则获取NULL 当然,我可以检查getconcenter是否返回桌面窗口,但这对我来说似乎是一种攻击。以下是我的想法: // // Returns the real parent window

MSDN对
GetParent
函数作了如下说明:

获取父窗口而不是 所有者不使用
GetParent
,而是与
GA_父项
标志

但是当调用
get祖先(hWnd,GA_PARENT)时
对于没有父窗口的窗口,它返回桌面窗口,而
GetParent
返回
NULL

那么,获取父对象(而不是所有者)的正确方法是什么?如果没有,则获取
NULL


当然,我可以检查
getconcenter
是否返回桌面窗口,但这对我来说似乎是一种攻击。

以下是我的想法:

//
// Returns the real parent window
// Same as GetParent(), but doesn't return the owner
//
HWND GetRealParent(HWND hWnd)
{
    HWND hParent;

    hParent = GetAncestor(hWnd, GA_PARENT);
    if(!hParent || hParent == GetDesktopWindow())
        return NULL;

    return hParent;
}

一个稍微好一点的版本,可以同时执行两个“路由”,如果找不到合适的父级,它将返回窗口本身(以避免空引用)。 在我的案例中,使用GetParent而不是getSenator是有效的,并返回了我想要的窗口

    public static IntPtr GetRealParent(IntPtr hWnd)
    {
        IntPtr hParent;

        hParent = GetAncestor(hWnd, GetAncestorFlags.GetParent);
        if (hParent.ToInt64() == 0 || hParent == GetDesktopWindow())
        { 
            hParent = GetParent(hWnd);
            if (hParent.ToInt64() == 0 || hParent == GetDesktopWindow())
            { 
                hParent = hWnd;
            }

        }

        return hParent;
    }

考虑到最新的Win32文档,于2020年更新:

HWND GetRealParent(HWND hWnd)
{
    HWND hWndOwner;

    // To obtain a window's owner window, instead of using GetParent,
    // use GetWindow with the GW_OWNER flag.

    if (NULL != (hWndOwner = GetWindow(hWnd, GW_OWNER)))
        return hWndOwner;

    // Obtain the parent window and not the owner
    return GetAncestor(hWnd, GA_PARENT);
}

正确的方法是调用get祖先并检测桌面。顶级窗口的父窗口是桌面窗口。与GetDesktopWindow()的值进行比较以检测这一点,这并不完全是一种黑客行为,除非您同时修补多个桌面。否则这会变得复杂,因为SetParent()支持Windows 3.x程序,而将另一个进程的窗口用作父进程并不是一个坏主意。所以你说桌面窗口对于不同的监视器是不同的?我该怎么办?不,他没那么说。他说不同的桌面。这是Windows很少使用的功能,它允许您在每个窗口站创建多个桌面。这些可以在两种模式之间切换。此功能最明显的用途是用于显示UAC对话框的桌面。我假设一个应用程序通常无法与其他桌面的窗口进行交互。谢谢你们的帮助,我正在发布一个答案!