Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to : Given HWND, discover if window is Modal or not

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");
                    }
                }
            }
        }
like image 847
CodeMinion Avatar asked Apr 25 '11 23:04

CodeMinion


People also ask

How do I find modal windows?

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.

Is modal dialog is blocking window?

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.

What is a modal vs dialog?

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.

What is Hwnd C#?

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.


2 Answers

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.

like image 93
eugen_nw Avatar answered Nov 07 '22 21:11

eugen_nw


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.

  • Check that the HWND is actually a top-level dialog, and not a child window
  • Get the owner (GetWindow(GW_OWNER))
  • Check that the owner is itself a top-level window (eg. GetAncestor(GA_PARENT)==GetDesktopWindow())
  • Check that the owner is disabled (GetWindowLong(GWL_STYLE) & WS_DISABLED)

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.

like image 24
BrendanMcK Avatar answered Nov 07 '22 20:11

BrendanMcK