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");
}
}
}
}
Type Ctrl+F to call up the Find dialog. This is a modeless dialog: The main window is still interactive. While the Find dialog is up, call up the About dialog from the Help menu.
A modal window creates a mode that disables the main window but keeps it visible, with the modal window as a child window in front of it. Users must interact with the modal window before they can return to the parent application.
Modal windows, by their nature, are compulsory and require the user to act immediately. Since the dialogs place the system in a different mode, users cannot continue what they are doing until they acknowledge the dialog.
In Win32, a window object is identified by a value known as a window handle. And the type of a window handle is an HWND (although it surfaces in C# as an IntPtr). In any case, you'll hear the term HWND used as a shorthand for window handle.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With