[再次尚未修訂爲清晰起見]如何自動化彈出模態HTML對話框的IE Web應用程序?
我有一個C++程序,它與網站交互。該網站是特定於IE的,我的程序也是如此。
我以普通方式連接到IE的運行實例(超出處理範圍 - 請參閱代碼)。一旦我得到IWebBrowser2
,我沒有問題得到IHTMLDocument2
和與個人IHTMLElement
對象交互,填寫字段和單擊按鈕。
但是,如果網頁有JavaScript,調用window.showModalDialog,我卡住了:我需要與彈出窗口中的HTML元素進行交互,就像其他頁面一樣;但我似乎無法得到其IWebBrowser2
。
彈出總是名爲「網頁對話框」,並且是包含Internet Explorer_Server
型Internet Explorer_TridentDlgFrame
的一個窗口。但是我無法從我的方式從Internet Explorer_Server
窗口獲取IWebBrowser2,這是一個普通的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
}
}
}
在它的問題的情況下正常工作,這是Vista的和IE8。 (我強調這一點,因爲這兩個引入了我的代碼庫中的突破性變化,這在XP/IE7中運行良好。)
再次,我的目標是獲得每個IHTMLElement
並與它交互。我無法訪問自動化的應用程序的源代碼。
我在考慮盲目發送按鍵到Internet Explorer_Server
窗口,但寧願不要。
編輯補充:
有人建議讓子窗口和發送他們的消息,但我敢肯定,不Internet Explorer_Server
工作;根據Spy ++,沒有任何子窗口。 (這不是IE特有的。Java小程序似乎並不有子窗口,無論是。)
更新
在評論中,西蒙毛雷爾說,上面的代碼爲他工作,而只是爲了確保沒有錯別字,他非常慷慨地在pastebin上發佈了一個完整的獨立應用程序。當我使用他的代碼時,它在同一個地方以相同的方式失敗,我意識到他以爲我想連接底層頁面,而不是彈出窗口。所以我編輯了上面的文字以消除這種模糊性。
什麼是例外?調用'pDoc-> QueryInterface'時'pDoc'看起來有效嗎? –
@NateHekman:我已經大幅修改了這個問題。 – egrunin
你能確認C++應用程序是否在進程外?什麼是「網頁對話框」?是腳本調用showModalDialog時彈出的IE窗口? –