From 90a254a9a89ce4421c52fba0de04197863a810f6 Mon Sep 17 00:00:00 2001 From: ivan-danilov Date: Mon, 30 Dec 2013 20:18:22 +0200 Subject: [PATCH] On Application.Close() instead of closing main window only it is better to close everything we can - there can be more than one window, e.g. in case of multi-threaded UI case. --- src/TestStack.White/Application.cs | 6 ++- .../WindowsAPI/NativeWindow.cs | 45 ++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/TestStack.White/Application.cs b/src/TestStack.White/Application.cs index 1969acb4..81aba620 100644 --- a/src/TestStack.White/Application.cs +++ b/src/TestStack.White/Application.cs @@ -10,6 +10,7 @@ using TestStack.White.Sessions; using TestStack.White.UIItems.Finders; using TestStack.White.UIItems.WindowItems; +using TestStack.White.WindowsAPI; namespace TestStack.White { @@ -215,7 +216,10 @@ public virtual void Close() Process.Dispose(); return; } - Process.CloseMainWindow(); + foreach (var window in NativeWindow.GetProcessWindows(Process.Id)) + { + window.PostCloseMessage(); + } Process.WaitForExit(5000); if (!Process.HasExited) { diff --git a/src/TestStack.White/WindowsAPI/NativeWindow.cs b/src/TestStack.White/WindowsAPI/NativeWindow.cs index f8ce0006..acf44b78 100644 --- a/src/TestStack.White/WindowsAPI/NativeWindow.cs +++ b/src/TestStack.White/WindowsAPI/NativeWindow.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Windows; @@ -20,6 +21,43 @@ public class NativeWindow [DllImport("gdi32.dll")] private static extern COLORREF GetTextColor(IntPtr hdc); + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); + + private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); + + [DllImport("user32.dll", SetLastError = true)] + private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool IsWindowEnabled(IntPtr hWnd); + + [return: MarshalAs(UnmanagedType.Bool)] + [DllImport("user32.dll", SetLastError = true)] + private static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); + + private const uint WM_CLOSE = 0x0010; + + public static IEnumerable GetProcessWindows(int processId) + { + var result = new List(); + Func processWindow = hwnd => + { + if (IsWindowEnabled(hwnd)) + { + int pid; + GetWindowThreadProcessId(hwnd, out pid); + if (pid == processId) + result.Add(new NativeWindow(hwnd)); + } + return true; + }; + EnumWindows((wnd, param) => processWindow(wnd), IntPtr.Zero); + return result; + } + public NativeWindow(Point point) { handle = WindowFromPoint(new POINT((int) point.X, (int) point.Y)); @@ -45,5 +83,10 @@ public virtual COLORREF TextColor return GetTextColor(GetDC(handle)); } } + + public virtual void PostCloseMessage() + { + PostMessage(handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); + } } -} +} \ No newline at end of file