[Пересмотренный еще раз для ясности]Как автоматизировать IE webapp, который появляется модальный диалог HTML?
У меня есть программа C++, которая взаимодействует с веб-сайта. Сайт является специфичным для IE, и моя программа тоже.
Я подключаюсь к исполняемому экземпляру IE обычным способом (не работает - см. Код). После того, как я получаю IWebBrowser2
, у меня нет проблем с получением в IHTMLDocument2
и взаимодействующий с отдельными IHTMLElement
объектов, заполнение полей и нажав кнопки.
Но если на веб-странице есть javascript, который вызывает window.showModalDialog, я застрял: мне нужно взаимодействовать с элементами HTML во всплывающем окне, как и на других страницах; но я не могу получить его IWebBrowser2
.
Всплывающее окно всегда называется «Диалог веб-страниц» и представляет собой окно типа Internet Explorer_TridentDlgFrame
, содержащее Internet Explorer_Server
. Но я не могу получить IWebBrowser2 из Internet Explorer_Server
окна так, как я могу, когда это обычный экземпляр IE.
я могу получить IHTMLDocument2Ptr
, но когда я пытаюсь получить IWebBrowser2
я получаю HRESULT
из E_NOINTERFACE
.
код довольно стандартный материал, и работает хорошо, если это «нормальный» окно IE
IHTMLDocument2Ptr pDoc;
LRESULT lRes;
/* hWndChild is an instance of class "Internet Explorer_Server" */
UINT nMsg = ::RegisterWindowMessage("WM_HTML_GETOBJECT");
::SendMessageTimeout(hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000,
(DWORD*)&lRes);
LPFNOBJECTFROMLRESULT pfObjectFromLresult =
(LPFNOBJECTFROMLRESULT)::GetProcAddress(hInst, "ObjectFromLresult");
if (pfObjectFromLresult != NULL)
{
HRESULT hr;
hr = (*pfObjectFromLresult)(lRes, IID_IHTMLDocument, 0, (void**)&pDoc);
if (SUCCEEDED(hr)) {
IServiceProvider *pService;
hr = pDoc->QueryInterface(IID_IServiceProvider, (void **) &pService);
if (SUCCEEDED(hr))
{
hr = pService->QueryService(SID_SWebBrowserApp,
IID_IWebBrowser2, (void **) &pBrowser);
// This is where the problem occurs:
// hr == E_NOINTERFACE
}
}
}
В случае, если это имеет значение, это Виста и IE8. (Я подчеркиваю это, потому что оба из них вносили изменения в мою кодовую базу, которая отлично работала с XP/IE7.)
Опять же, моя цель - получить каждый IHTMLElement
и взаимодействовать с ним. У меня нет доступа к исходному коду приложения, которое я автоматизирую.
Я рассматриваю отправки нажатий клавиш вслепую в Internet Explorer_Server
окне, но не хотелось бы.
Edited добавить:
Кто-то предложил получать дочерние окна и отправлять им сообщения, но я уверен, что не работает с Internet Explorer_Server
; согласно Spy ++, нет никаких дочерних окон. (Это не IE-специфичны. Java-апплеты, кажется, не имеют дочерние окна, либо.)
Update
В комментариях, Саймон Maurer сказал выше код работал на него, и просто убедитесь, что нет опечаток, он очень щедро разместил полное автономное приложение на pastebin. Когда я использовал свой код, он не так же, как в том же месте, и я понял, что он думал, что я хотел подключиться к странице основного, а не в выпадающем меню. Поэтому я отредактировал текст выше, чтобы удалить эту двусмысленность.
В чем исключение? Действительно ли 'pDoc' выглядит действительным, когда вы вызываете' pDoc-> QueryInterface'? –
@NateHekman: Я существенно пересмотрел вопрос. – egrunin
Можете ли вы подтвердить, что приложение C++ не работает? Что такое «диалог веб-страницы»? Это окно IE появляется, когда скрипт вызывает showModalDialog? –