После того, как у вас есть процесс, вы можете все перечислить Windows, в процессе и тестирования, если какой-либо из них соответствуют интересующему вас окну.
Вам понадобится следующее P/Invoke деклараций
[DllImport("user32", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
private extern static bool EnumThreadWindows(int threadId, EnumWindowsProc callback, IntPtr lParam);
[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)]
private extern static int GetWindowText(IntPtr hWnd, StringBuilder text, int maxCount);
followng является примером пары функций, которые могут быть использованы, чтобы найти окно в определенном процессе, я понял из вашего вопроса, что вам есть процесс, проблема заключается в перечислении окон.
public static IntPtr FindWindowInProcess(Process process, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
foreach (ProcessThread t in process.Threads)
{
windowHandle = FindWindowInThread(t.Id, compareTitle);
if (windowHandle != IntPtr.Zero)
{
break;
}
}
return windowHandle;
}
private static IntPtr FindWindowInThread(int threadId, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
EnumThreadWindows(threadId, (hWnd, lParam) =>
{
StringBuilder text = new StringBuilder(200);
GetWindowText(hWnd, text, 200);
if (compareTitle(text.ToString()))
{
windowHandle = hWnd;
return false;
}
return true;
}, IntPtr.Zero);
return windowHandle;
}
Тогда вы можете вызвать функцию FindWindowInProcess найти окно, которое название заканчивается «ABC» в качестве примера.
IntPtr hWnd = FindWindowInProcess(p, s => s.EndsWith("ABC"));
if (hWnd != IntPtr.Zero)
{
// The window was found....
}
Конечно, вы можете заменить s => s.EndsWith («ABC») с любым выражением, которое будет удовлетворять ваши критерии поиска для окна, это может быть регулярным выражением и т.д.
Здесь также версию FindThreadWindow, которая также проверит первый уровень дочерних окон. Вы можете сделать это дальше и сделать его рекурсивной функцией, если ваши окна будут глубже в иерархии.
private static IntPtr FindWindowInThread(int threadId, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
EnumThreadWindows(threadId, (hWnd, lParam) =>
{
StringBuilder text = new StringBuilder(200);
GetWindowText(hWnd, text, 200);
if (compareTitle(text.ToString()))
{
windowHandle = hWnd;
return false;
}
else
{
windowHandle = FindChildWindow(hWnd, compareTitle);
if (windowHandle != IntPtr.Zero)
{
return false;
}
}
return true;
}, IntPtr.Zero);
return windowHandle;
}
private static IntPtr FindChildWindow(IntPtr hWnd, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
EnumChildWindows(hWnd, (hChildWnd, lParam) =>
{
StringBuilder text = new StringBuilder(200);
GetWindowText(hChildWnd, text, 200);
if (compareTitle(text.ToString()))
{
windowHandle = hChildWnd;
return false;
}
return true;
}, IntPtr.Zero);
return windowHandle;
}
очень сложный ответ, работает как шарм. – Axarydax
В FindChildWindow ... не должно быть hChildWnd вместо hWnd после проверки результата compareTitle? – seveves