Чтобы найти все традиционные окна 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);