Reputation: 653
For any given window I handle, I need a way to find out whether or not the given window is Modal.
Far as I can tell, there are no methods that do exactly that, which is why I need some clever workaround to work this out!
Help is appreciated!
EDIT : Why is my GetWindow(,GW_OWNER) failing? :(
[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");
}
}
}
}
Upvotes: 12
Views: 6890
Reputation: 14488
Modal windows usually work by disabling their owner, where the owner is a top-level window. So if you test for this situation, you should catch whether a dialog is modal or not.
That should catch all standard Win32-style modal dialogs.
Note that parent and owner are subtly different concepts; it's the owner you want to check here. This can get confusing, because GetParent can return the owner... - more details from Raymond Chen here.
Upvotes: 10
Reputation: 159
I'm not certain that BrendanMck's solution will always be correct. Let's say that window W displays first a modeless dialog A and then a modal dialog B. Both A and B have W as their parent window. At the time B was displayed, W became disabled and as such applying the algorithm to both A and B will report both of them as being modal dialogs.
Upvotes: 3
Reputation: 1
I just wrote
GetWindowLong(GetWindow(Hwnd, GW_OWNER), GWL_STYLE) & WS_DISABLED & WS_POPUP
in my code.
Upvotes: -2