У меня есть многопоточный инструмент для тестирования пользовательского интерфейса, который запускает экземпляры Internet Explorer. Я хотел бы найти окно предупреждения javascript, используя API PInvoke.Найти окно предупреждения javascript в процессе IE
Поиск глобально работает отлично:
IntPtr globalAlertHwnd = Pinvoke.FindWindow("#32770", "Message from webpage");
Однако, поскольку я бегу несколько экземпляров IE параллельно, я хочу, чтобы предназначаться конкретную форму оповещения на основе его IE родителя.
я могу найти его в глобальной куче указателей, а также:
IntPtr desktopHwnd = Pinvoke.GetDesktopWindow();
List<IntPtr> allDesktopChilds = Pinvoke.GetChildWindows(desktopHwnd).ToList();
bool match1 = allDesktopChilds.Any(hwnd => hwnd == globalAlertHwnd); // true
Но как только я использую процесс IE, я не могу найти его. mainWindowHnadle
- это ручка окна IE.
List<IntPtr> ieChildren = Pinvoke.EnumerateProcessWindowHandles(mainWindowHnadle).ToList();
bool match2 = ieChildren.Any(hwnd => hwnd == globalAlertHwnd); // false
Вот как выглядит EnumerateProcessWindowHandles
:
public static IEnumerable<IntPtr> EnumerateProcessWindowHandles(IntPtr hwnd)
{
List<IntPtr> handles = new List<IntPtr>();
uint processId;
GetWindowThreadProcessId(hwnd, out processId);
foreach (ProcessThread thread in Process.GetProcessById((int)processId).Threads)
{
EnumThreadWindows(thread.Id, (parentHwnd, lParam) =>
{
handles.Add(parentHwnd);
List<IntPtr> childHwnds = GetChildWindows(parentHwnd);
handles.AddRange(childHwnds);
return true;
}, IntPtr.Zero);
}
return handles;
}
public static List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
Win32Callback childProc = new Win32Callback(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
Я знаю, что EnumChildWindows()
получает все детей, а не только верхний уровень (проверяется мой второй пример).
Я проверил, что окно предупреждения существует в одном из потоков IE вместе с кнопкой ОК. Spy ++ скриншот:
Что мне не хватает? Этот метод отлично работает как в Firefox, так и в Chrome.
UPDATE:
Похоже, эта проблема возникает потому, что IE создает один процесс для главного окна, и другой процесс для каждой вкладки. Я должен подумать о том, как получить другой процесс на основе этого.