Как: учитывая HWND, узнайте, является ли окно модальным или нет
для любого заданного окна, которое я обрабатываю, мне нужен способ узнать, является ли данное окно модальным.
насколько я могу судить, нет методов, которые делают именно это, поэтому мне нужно какое-то умное обходное решение для этого!
помощь приветствуется!
EDIT: почему мое 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");
}
}
}
}
3 ответов
модальные окна обычно работают, отключая их владельца, где владелец является окном верхнего уровня. Поэтому, если вы проверяете эту ситуацию, вы должны поймать, является ли диалог модальным или нет.
- проверьте, что HWND на самом деле является диалогом верхнего уровня, а не дочерним окном
- получить владельца (GetWindow (GW_OWNER))
- проверяем, что владелец сам является окном верхнего уровня (например. GetAncestor (GA_PARENT)==GetDesktopWindow ())
- проверьте, что владелец отключено (GetWindowLong (GWL_STYLE) & WS_DISABLED)
Это должно поймать все стандартные модальные диалоги Win32-стиля.
обратите внимание, что родитель и владелец-это тонко разные понятия; это владелец, которого вы хотите проверить здесь. Это может запутаться, потому что GetParent может вернуть владельца... - более подробная информация от Raymond Chen здесь.
Я не уверен, что решение Бренданмка всегда будет правильным. Предположим, что окно W отображает сначала немодальный диалог A, а затем модальный диалог B. Оба A и B имеют W в качестве родительского окна. Во время отображения B W был отключен, и поэтому применение алгоритма как к A, так и к B сообщит о том, что оба они являются модальными диалогами.
Я только что написал
GetWindowLong(GetWindow(Hwnd, GW_OWNER), GWL_STYLE) & WS_DISABLED & WS_POPUP
в моем коде.