Reputation: 91
I'm writing an application that latches on to another, which I don't have the source code for, but there's a certain thing that makes it display a .NET Framework exception message.
I can detect with my code when it will open, and I want to get its handle and close it. Sometimes this child window takes the title from the main window, so I can't rely on that to find its handle.
An image of the child window in question:
Upvotes: 1
Views: 2104
Reputation: 91
Ok, I solved it. It turns out that the GetForegroundWindow() was returning the correct handle, however, since sometimes the exception window takes the title from the parent I was getting tripped up.
The solution is to wait until the number of windows changes using EnumWindows, then get the handle of the foreground window and close it.
new Thread(() =>
{
int pid = Program.GetHelperProcess().Id;
int lastCount = -1;
while (true)
{
int newCount = WinUtil.GetWindowCount(pid);
if (lastCount != -1 && lastCount != newCount)
{
break;
}
lastCount = newCount;
Thread.Sleep(30);
}
WinUtil.CloseWindow(WinUtil.GetForegroundWindow());
}).Start();
WinUtil.cs
class WinUtil
{
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
private delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);
[DllImport("user32.dll")]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll")]
private static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr GetShellWindow();
public static int GetWindowCount(int processId)
{
IntPtr hShellWindow = GetShellWindow();
int count = 0;
EnumWindows(delegate (IntPtr hWnd, int lParam)
{
if (hWnd == hShellWindow) return true;
if (!IsWindowVisible(hWnd)) return true;
int length = GetWindowTextLength(hWnd);
if (length == 0) return true;
uint windowPid;
GetWindowThreadProcessId(hWnd, out windowPid);
if (windowPid != processId) return true;
count++;
return true;
}, 0);
return count;
}
public static string GetWindowTitle(IntPtr hWnd)
{
int textLength = GetWindowTextLength(hWnd);
StringBuilder outText = new StringBuilder(textLength + 1);
int a = GetWindowText(hWnd, outText, outText.Capacity);
return outText.ToString();
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
private const UInt32 WM_CLOSE = 0x0010;
public static void CloseWindow(IntPtr hwnd)
{
SendMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
}
Upvotes: 2