Winapi 获取父窗口的正确方法
MSDN对Winapi 获取父窗口的正确方法,winapi,Winapi,MSDN对GetParent函数作了如下说明: 获取父窗口而不是 所有者不使用GetParent,而是与 GA_父项标志 但是当调用get祖先(hWnd,GA_PARENT)时对于没有父窗口的窗口,它返回桌面窗口,而GetParent返回NULL 那么,获取父对象(而不是所有者)的正确方法是什么?如果没有,则获取NULL 当然,我可以检查getconcenter是否返回桌面窗口,但这对我来说似乎是一种攻击。以下是我的想法: // // Returns the real parent window
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对话框的桌面。我假设一个应用程序通常无法与其他桌面的窗口进行交互。谢谢你们的帮助,我正在发布一个答案!