[ Пересмотрено еще раз для ясности]
У меня есть программа на С++, которая взаимодействует с веб-сайтом. Сайт является специфичным для 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
}
}
}
В случае, если это важно, это Vistastrong > и IE8. (Я подчеркиваю это, потому что оба из них вносили изменения в мою кодовую базу, которая отлично работала с XP/IE7.)
И снова моя цель - получить каждый IHTMLElement
и взаимодействовать с ним. У меня нет доступа к исходному коду приложения, которое я автоматизирую.
Я рассматриваю возможность отправки нажатий клавиш в окно Internet Explorer_Server
, но скорее не будет.
Отредактировано для добавления:
Кто-то предложил получить дочерние окна и отправить их сообщениям, но я уверен, что не работает с Internet Explorer_Server
; согласно Spy ++, нет никаких дочерних окон. (Это не зависит от IE. Аплеты Java, похоже, не имеют дочерних окон.)
Обновление
В комментариях Саймон Маурер сказал, что приведенный выше код работал для него, и чтобы убедиться, что нет опечаток, он очень щедро разместил полное автономное приложение на pastebin. Когда я использовал его код, он потерпел неудачу точно так же в одном и том же месте, и я понял, что он думал, что я хочу подключиться к базовой странице, а не всплывающей. Поэтому я отредактировал текст выше, чтобы удалить эту двусмысленность.