Detecting if Word has a Dialog Open

There are a few scenarios where you may want to know if Word has a modal or non-modal dialog open. The following approach will used the FindWindowEx Windows API function to determine if there is a window open in Word. This list of probably far from complete, but will get you started. To add a window, use Spy++ to get the ClassName of a window that has appeared in Word.

NOTE: This technique can also work for Excel, PowerPoint and Outlook (probably) as well – although not tested in anything but Word.

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);

[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

/// <summary>
/// Helper function to see if Word has any dialogs open
/// </summary>
/// <returns></returns>
private bool hasNonModalWindow()
{
    const string WIN_CLASS = "bosa_sdm_msword";
    const string NUI_CALSS = "NUIDialog";
    // look for known non-modal dialog types
    IntPtr hNui = GetChildWindowHandle(NUI_CALSS);
    IntPtr hWin = GetChildWindowHandle(WIN_CLASS);
    // if we get handles from above then return true
    return (hNui != IntPtr.Zero || hWin != IntPtr.Zero);
}

/// <summary>
/// Utility function using Windows API cals to loop though
/// child windows of Word and see if there are any that
/// match the passed in child class name. If there are
/// then we return the pointer to that window.
/// </summary>
/// <param name="winClass"></param>
/// <returns></returns>
private IntPtr GetChildWindowHandle(string winClass)
{
    IntPtr hWin = IntPtr.Zero;
    hWin = FindWindowEx(IntPtr.Zero, hWin, winClass, null);
    uint PID = 0;
    while (hWin != IntPtr.Zero)
    {
        // Make sure that the  window handle that we got is for the current running
        // process of Word. We do this by checking if the PID for this window and 
        // Word are same.
        GetWindowThreadProcessId(hWin, out PID);
        if (PID == Process.GetCurrentProcess().Id)
            break;
        // get next window
        hWin = FindWindowEx(IntPtr.Zero, hWin, winClass, String.Empty);
    }
    return hWin;
}

Here is an example using the function above:

// Call the function o see if the known window
// types for Word can be found and if any are found
// let the usr know....
if (hasNonModalWindow())
    MessageBox.Show("Word has a window open.");
else
    MessageBox.Show("There are no windows open in Word.");

Leave a Reply