2015-12-04 2 views
2

У меня есть многопоточный инструмент для тестирования пользовательского интерфейса, который запускает экземпляры 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 ++ скриншот:

enter image description here

Что мне не хватает? Этот метод отлично работает как в Firefox, так и в Chrome.

UPDATE:

Похоже, эта проблема возникает потому, что IE создает один процесс для главного окна, и другой процесс для каждой вкладки. Я должен подумать о том, как получить другой процесс на основе этого.

ответ

0

решаемые заставляя IE, чтобы создать единый процесс для каждого экземпляра:

Создание или обновление реестра ключ TabProcGrowth в HKEY_CURRENT_USER\Software\MicrosoftInternet Explorer\Main. Он должен быть 32-битным REG_DWORD со значением 0.

Смежные вопросы