对于我处理的任何给定窗口,我需要一种方法来确定给定窗口是否为模态。
据我所知,没有哪种方法可以做到这一点,这就是为什么我需要一些聪明的解决方法来解决这个问题!
非常感谢帮助!
编辑:为什么我的GetWindow(,GW_OWNER)失败了? :(
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);
[DllImport("user32.dll", ExactSpelling = true)]
internal static extern IntPtr GetAncestor(IntPtr hwnd, GetAncestor_Flags gaFlags);
[DllImport("user32.dll", SetLastError = false)]
internal static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll", SetLastError = true)]
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
const UInt32 WS_DISABLED = 0x8000000;
internal enum GetAncestor_Flags
{
GetParent = 1,
GetRoot = 2,
GetRootOwner = 3
}
internal enum GetWindow_Cmd : uint
{
GW_HWNDFIRST = 0,
GW_HWNDLAST = 1,
GW_HWNDNEXT = 2,
GW_HWNDPREV = 3,
GW_OWNER = 4,
GW_CHILD = 5,
GW_ENABLEDPOPUP = 6
}
IntPtr _inspHwnd = FindWindow("rctrl_renwnd32", inspector.Caption); // searching for a window with this name
if (_inspHwnd.ToInt32() != 0) // found window with this name
{
IntPtr _ownerHwnd = GetWindow(_inspHwnd, GetWindow_Cmd.GW_OWNER);
if (_ownerHwnd.ToInt32() != 0)
{
IntPtr _ancestorHwnd = GetAncestor(_ownerHwnd, GetAncestor_Flags.GetParent);
if (_ancestorHwnd == GetDesktopWindow())
{
if (GetWindowLong(_ancestorHwnd, -16) == WS_DISABLED)
{
// inspector is probably modal if you got all the way here
MessageBox.Show("modal flag tripped");
}
}
}
}
答案 0 :(得分:8)
模态窗口通常通过禁用其所有者来工作,其中所有者是顶级窗口。因此,如果您测试这种情况,您应该检查对话框是否是模态的。
应该捕获所有标准的Win32风格的模态对话框。
请注意,父母和所有者是微妙不同的概念;这是你想在这里查看的主人。这可能会让人感到困惑,因为GetParent可以归还所有者...... - 来自Raymond Chen here的更多细节。
答案 1 :(得分:1)
我不确定BrendanMck的解决方案总是正确的。让我们说窗口W首先显示无模式对话框A然后显示模态对话框B.A和B都将W显示为其父窗口。在显示B时,W被禁用,因此将算法应用于A和B都会将它们都报告为模态对话框。
答案 2 :(得分:0)
我刚才写道
GetWindowLong(GetWindow(Hwnd, GW_OWNER), GWL_STYLE) & WS_DISABLED & WS_POPUP
在我的代码中。