Ahmed
Ahmed

Reputation: 15029

Detecting a modal dialog box of another process

I want to detect whether another process say process.exe is currently displaying a dialog box ? Is there a way to do that in C# ?

To see if I could get the handle of the dialog box. I have tried Spy++ 's find window tool, when I try to drag the finder on top of the dialog box, it does not highlight the dialogbox but populates the details and mentions AppCustomDialogBox and mentions the handle number

Please advise how can I programatically detect that ..

Thanks,

Upvotes: 7

Views: 8869

Answers (2)

Deanna
Deanna

Reputation: 24253

As modal dialogs normally disable the parent window(s), you can enumerate all top level windows for a process and see if they're enabled using the IsWindowEnabled() function.

Upvotes: 3

user1261537
user1261537

Reputation:

When an application shows a dialog box, the (for me quietly annoying) behaviour of Windows Operating System is to show the newly created window on top of all other. So if I assume that You know which process to watch, a way to detect a new window is to set up a windows hook:

    delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
    IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);

    [DllImport("user32.dll")]
    public static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr
       hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,
       uint idThread, uint dwFlags);

    [DllImport("user32.dll")]
    public static extern bool UnhookWinEvent(IntPtr hWinEventHook);

    // Constants from winuser.h
    public const uint EVENT_SYSTEM_FOREGROUND = 3;
    public const uint WINEVENT_OUTOFCONTEXT = 0;

    //The GetForegroundWindow function returns a handle to the foreground window.
    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();
    // For example, in Main() function
    // Listen for foreground window changes across all processes/threads on current desktop
    IntPtr hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero,
            new WinEventDelegate(WinEventProc), 0, 0, WINEVENT_OUTOFCONTEXT);


    void WinEventProc(IntPtr hWinEventHook, uint eventType,
    IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
    {     
          IntPtr foregroundWinHandle = GetForegroundWindow();
          //Do something (f.e check if that is the needed window)
    }

    //When you Close Your application, remove the hook:
    UnhookWinEvent(hhook);

I did not try that code explicitely for dialog boxes, but for separate processes it works well. Please remember that that code cannot work in a windows service or a console application as it requires a message pump (Windows applications have that). You'll have to create an own.

Hope this helps

Upvotes: 5

Related Questions