关闭WPF应用程序中的打开对话框(不仅仅是窗口)。

3

根据在这里找到的解决方案,我能够遍历Application.Current.Windows列表并在退出系统时关闭它们。然而,可能会有一个对话框(例如OpenFileDialog)打开;不幸的是,这个对话框不在Current.Windows集合中。是否有其他方法来确保所有这样的对话框都被关闭(而不必将它们存储在某个地方的集合中?)


这听起来像是你正在寻找Win32窗口。你尝试过使用Win32函数来检查主窗口的所有非WPF子窗口吗? - Ed Bayiates
有趣的想法。我该如何着手去做这件事呢(请原谅我的无知)? - Mani5556
没什么好道歉的,这就是这个网站存在的意义。既然你有兴趣,我马上会把它作为答案添加进去。 - Ed Bayiates
1个回答

2

要查找所有传统的Win32窗口,您需要枚举线程上的窗口并关闭它们。

一些有用的函数和常量声明:

[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;

你需要一个委托声明来回调枚举子项:
public delegate bool EnumThreadFindWindowDelegate(IntPtr hwnd, IntPtr lParam);

回调函数本身会关闭找到的每个窗口。如果有您不想关闭的窗口,例如顶级窗口,则需要添加自己的条件。下面我已经添加了一些注释代码来获取窗口标题,例如。

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;
}

进行枚举:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接