简体   繁体   中英

Close open DialogBoxes (not just windows) in a WPF application

Based on the solution found here I am able to iterate through a list of Application.Current.Windows and close them upon logging out of my system. However, there is a possibility that a Dialog (OpenFileDialog or the like) may be open; unfortunately, this dialog is not in the collection of Current.Windows. Is there any other way to ensure that all such dialogs get closed (without having to store a collection of them somewhere, for instance?)

To find all the traditional Win32 windows, you will want to enumerate the windows on your thread(s) and close them.

Declarations of some helpful functions and a constant:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hwnd, IntPtr processId);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadFindWindowDelegate lpfn, IntPtr lParam);
[DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)]
private extern static int GetWindowText(IntPtr hWnd, StringBuilder text, int maxCount);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(int hWnd, int Msg, int wParam, int lParam);

const uint WM_CLOSE = 0x10;

You need a delegate declaration for the callback to enum the children:

public delegate bool EnumThreadFindWindowDelegate(IntPtr hwnd, IntPtr lParam);

The callback itself, which closes each window found. You will want to add your own criteria here if there are windows you do not want closed, eg your top level window. I've added some commented out code below to get the window title, for example.

static bool EnumThreadCallback(IntPtr hWnd, IntPtr lParam)
{
    // If you want to check for a non-closing window by title...
    // Get the window's title
    //StringBuilder text = new StringBuilder(500);
    //GetWindowText(hWnd, text, 500);

    SendMessage(hWnd, WM_CLOSE, 0, 0);

    // Continue
    return true;
}

To do the enumeration:

uint threadId = Thread.CurrentThread.ManagedThreadId;
EnumThreadWindows(threadId, EnumThreadCallback, IntPtr.Zero);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM