Открыть вкладку в IE8 с помощью SendMessage() С#

В приведенном ниже коде hWnd является «дескриптором URL» в Spy++:

'WorkerW -> ReBarWindow32 -> Address Band Root -> Edit' 

URL - это то, что я хочу открыть.

Я использую тот же метод, чтобы открывать вкладки в IE7 и соответствующим образом отправлять hWnd. Я вижу, что это отлично работает для IE7, а не для IE8. В IE8 открывается только 4 вкладки, а затем IE8 перестает выполнять запрос SendMessage; тем не менее, я все еще могу нажать CTRL+T ИЛИ ALT+Enter, чтобы открыть новые вкладки в IE8 (поэтому IE8 по-прежнему реагирует).

/**
 * Open URL in IE (open new tab when newTab is true)
 * hWnd is found at runtime 
 **/
private void LaunchURLinIE(IntPtr hWnd, String url, bool newTab = false)
{
    StringBuilder ob = new StringBuilder(url);
    // Type text in the URL window
    SendMessage(hWnd, WM_SETTEXT, 0, ob);
    if (!newTab)
    {   // Press Enter
        SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, 1);
    }
    else
    {   // Press ALT Enter to open new tab
        SendMessage(hWnd, WM_SYSKEYDOWN, VK_RETURN, 1 << 29);
    }
}

Моя среда: Windows XP с пакетом обновления 3 [32-разрядная ОС], IE8 версии 8.0.6001.18702

Итак, это IE8 или что-то, что мне не хватает?

ОБНОВЛЕНИЕ – 1 Я обновил комментарии к коду, чтобы было понятно, что делает код. Приведенный выше код отлично работает для IE7 (протестировано до 15 вкладок), но в IE8 открывается только до 4 вкладок.

Обновление - 2 Мне удалось решить эту проблему, используя PostMessage вместо SendMessage.

   private void LaunchURLinIE(IntPtr hWnd, String url, bool newTab = false)
    {
        StringBuilder ob = new StringBuilder(url);
        // Type text in the URL window
        SendMessage(hWnd, WM_SETTEXT, 0, ob);
        if (!newTab)
        {   // Press Enter
            PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 1);
        }
        else
        {   // Press ALT Enter to open new tab
            PostMessage(hWnd, WM_SYSKEYDOWN, VK_RETURN, 1 

person karephul    schedule 04.04.2011    source источник
comment
CTRL+TAB на самом деле не открывает новые вкладки. Он просто переключается на следующий, как ALT+TAB переключает окна приложений. Так что, если после запуска приложения открываются новые окна с помощью ALT+TAB, это может указывать на то, что... хм... вы сделали что-то не так. :)   -  person Tedd Hansen    schedule 04.04.2011
comment
Вы понимаете, что hWnd не является фиксированным значением, верно? Вы не можете просто получить его один раз с помощью Spy++ и использовать его с тех пор. Каждый раз, когда приложение закрывается и снова открывается (или повторно создается дескриптор элемента управления), значение будет меняться.   -  person Cody Gray    schedule 04.04.2011
comment
Почему вы пытаетесь напрямую манипулировать IE, чтобы открывать вкладки? Как правило, проще и надежнее использовать ShellExecute для запуска URL-адреса.   -  person Jon    schedule 04.04.2011
comment
@Cody - мы пытаемся управлять вкладками в окне, чтобы для выполнения подобных действий приложение открывало вкладку в существующем окне IE, в противном случае оно открывало новое окно IE. Мы отслеживаем дескриптор IE, а затем находим дескриптор редактирования, когда это необходимо.   -  person karephul    schedule 04.04.2011
comment
Я не знаю, что означает всякий раз, когда это необходимо. Вы вообще не должны следить за этим. Это деталь реализации, а не то, что должен отслеживать ваш код. В любом случае, как пытаются вам сказать другие, это неправильный способ сделать это и по множеству других причин. Мое предложение еще проще: измените настройки IE, чтобы новые страницы открывались в новой вкладке. автоматизация пользовательского интерфейса сложна; нет причин усложнять вещи без необходимости.   -  person Cody Gray    schedule 04.04.2011


Ответы (2)


Возможно, вы захотите попробовать использовать COM, предоставленный объектом ShDocVw, который можно найти как .dll с именем Interop.ShDocVw.dll, который содержит интерфейс InternetExplorerClass, который позволяет вам надежно выполнять большую часть автоматизации IE.

Я участник SWAT http://sourceforge.net/projects/ulti-swat/ , если вам нужны хорошие примеры, не стесняйтесь использовать наш исходный код для автоматизации IE, расположенный в SWAT.Core/InternetExplorer.cs.

На самом деле есть много проблем с вашим кодом, дескрипторы окон жестко запрограммированы (почему?), Кроме того, вы только отправляете клавишу вниз, приложение обычно ожидает комбинацию нажатия клавиши/нажатия клавиши или иногда последовательность нажатия клавиши/нажатия клавиши/нажатия клавиши, чтобы оно быть действительным. Ваше приложение создает впечатление, что вы удерживаете клавиши, которые отправляете. Вы можете использовать вызов Windows API FindWindow, который может помочь вам найти дескриптор окна во время выполнения для окна, в которое вы хотите отправлять сообщения.

person Jesus Ramos    schedule 04.04.2011
comment
Спасибо за совет, Рамос, мы планировали изучить это, но есть много изменений кода, чтобы включить Interop.ShDocVw.ll, и мы хотим быстро это исправить. Почему IE8 открывает только 4 вкладки с приведенным выше кодом, почему не больше? вот что я пытаюсь диагностировать. - person karephul; 04.04.2011
comment
Помните, что SendMessage отправляет сообщение приложению, и приложение запускает правильный обработчик для сообщения, нигде не гарантируется, что приложение ответит на сообщение, и для него совершенно законно полностью игнорировать сообщение. - person Jesus Ramos; 04.04.2011
comment
@Ramos: Спасибо за совет, я собираюсь более внимательно изучить этот фреймворк. Я уверен, что многому научусь из него. - person karephul; 05.04.2011

Не следует ли также отправить WM_KEYUP?

ВК_ВОЗВРАТ? Не уверен, что он делает. Было бы лучше вместо этого отправлять нажатия клавиш CTRL+T?

  • КОНТРОЛЬ КЛАВИШ
  • КЕЙДАУН Т
  • КЕЙУП Т
  • УПРАВЛЕНИЕ КЛАВИШЕЙ

Коды клавиш можно найти с помощью KeyInterop.VirtualKeyFromKey.

Я также думаю, что вам нужно использовать PostMessage:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
private static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

private const UInt32 WM_KEYDOWN = 0x0100;
private const UInt32 WM_KEYUP = 0x0101;

public static void IENewTab(IntPtr HWnd)
{
    PostMessage(HWnd, WM_KEYDOWN, KeyInterop.VirtualKeyFromKey(System.Windows.Input.Key.LeftCtrl), 0);
    PostMessage(HWnd, WM_KEYDOWN, KeyInterop.VirtualKeyFromKey(System.Windows.Input.Key.T), 0);
    PostMessage(HWnd, WM_KEYUP, KeyInterop.VirtualKeyFromKey(System.Windows.Input.Key.T), 0);
    PostMessage(HWnd, WM_KEYUP, KeyInterop.VirtualKeyFromKey(System.Windows.Input.Key.LeftCtrl), 0);
}
person Tedd Hansen    schedule 04.04.2011
comment
Отправка сообщения ctrl в неактивные окна, вероятно, невозможна, по крайней мере, я не смог этого сделать. Так что по моему не получится. REF: stackoverflow.com/questions /5144877/ - person karephul; 04.04.2011
comment
@karephul: Да, конечно, можно отправлять ввод с клавиатуры в неактивные окна. Для этого используется функция SendInput с подходящим названием. Кто сказал вам использовать PostMessage? Это не для генерации событий ввода с клавиатуры. - person Cody Gray; 05.04.2011
comment
@Cody: Да, мы можем отправлять обычные ключевые аисты в неактивное или не в фокусе окно, но я не смог отправить сообщение Ctrl в свернутое / неактивное или не в фокусе окно. Мне не удалось отправить сообщение Ctrl-S в окно блокнота, когда оно свернуто или не в фокусе. stackoverflow.com/questions/5144877 /. - person karephul; 05.04.2011