Цепляюсь к запущенному IE и через Invoke пытаюсь отлавливать события.
В частности нужно отловить DISPID_DOCUMENTCOMPLETE и распарсить html загруженной странички.
И оно приходит, и html из IWebBrowser2 правильный, но не всегда.
Через раз вместо него приходит DISPID_QUIT, что вообще говоря означает закрытие IE, хотя никакого закрытия нет.
И после этого начинается бред. DISPID_DOCUMENTCOMPLETE уже не приходит.
Но если походить по ссылкам в IE то оно придет, но при попытке взять html странички из IWebBrowser2 там либо совсем другая страничка, либо вообще ерунда типа "<html><head></head><body></body></html>".
То есть понятно, что где-то что-то отваливается, но как это предотвратить, или хотя бы перезапустить процесс нормального перехвата ?
class XWebBrowser2EventsBase
{
protected:
static _ATL_FUNC_INFO BeforeNavigate2Struct;
static _ATL_FUNC_INFO DocumentComplete2Struct;
static _ATL_FUNC_INFO NavigateErrorStruct;
static _ATL_FUNC_INFO OnQuitStruct;
static _ATL_FUNC_INFO OnVisibleStruct;
static _ATL_FUNC_INFO QuitStruct;
};
class XEventSink : public XWebBrowser2EventsBase, public IDispEventSimpleImpl<1, XEventSink, &DIID_DWebBrowserEvents2>
{
public:
XEventSink(class XBrowser* a_pBrowser);
~XEventSink();
BEGIN_SINK_MAP(XEventSink)
SINK_ENTRY_INFO(1, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, OnBeforeNavigate2, &BeforeNavigate2Struct)
SINK_ENTRY_INFO(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete, &DocumentComplete2Struct)
SINK_ENTRY_INFO(1, DIID_DWebBrowserEvents2, DISPID_NAVIGATEERROR, OnNavigateError, &NavigateErrorStruct)
SINK_ENTRY_INFO(1, DIID_DWebBrowserEvents2, DISPID_ONQUIT, OnQuit, &OnQuitStruct)
SINK_ENTRY_INFO(1, DIID_DWebBrowserEvents2, DISPID_ONVISIBLE, OnVisible, &OnVisibleStruct)
SINK_ENTRY_INFO(1, DIID_DWebBrowserEvents2, DISPID_QUIT, Quit, &QuitStruct)
END_SINK_MAP()
void Advise();
void UnAdvise();
READYSTATE GetReadyState();
void __stdcall OnBeforeNavigate2(IDispatch* pDisp, VARIANT* pvURL, VARIANT* pvFlags, VARIANT* pvTargetFrameName, VARIANT* pvPostData, VARIANT* pvHeaders, VARIANT_BOOL* pbCancel);
void __stdcall OnDocumentComplete(IDispatch* pDisp, VARIANT* pvURL);
void __stdcall OnNavigateError(IDispatch* pDisp, VARIANT* pvURL, VARIANT* pvTargetFrameName, VARIANT* pvStatusCode, VARIANT_BOOL* pbCancel);
void __stdcall OnQuit();
void __stdcall OnVisible(VARIANT_BOOL bVisible);
void __stdcall Quit();
XBrowser* m_pBrowser;
int m_cnt;
};
__declspec(selectany) _ATL_FUNC_INFO XWebBrowser2EventsBase::BeforeNavigate2Struct = { CC_STDCALL, VT_EMPTY, 7, { VT_DISPATCH,VT_BYREF | VT_VARIANT,VT_BYREF | VT_VARIANT,VT_BYREF | VT_VARIANT,VT_BYREF | VT_VARIANT,VT_BYREF | VT_VARIANT,VT_BYREF | VT_BOOL } };
__declspec(selectany) _ATL_FUNC_INFO XWebBrowser2EventsBase::DocumentComplete2Struct = { CC_STDCALL, VT_EMPTY, 2, { VT_DISPATCH, VT_BYREF | VT_VARIANT } };
__declspec(selectany) _ATL_FUNC_INFO XWebBrowser2EventsBase::NavigateErrorStruct = { CC_STDCALL, VT_EMPTY, 5, { VT_BYREF | VT_BOOL,VT_BYREF | VT_VARIANT,VT_BYREF | VT_VARIANT,VT_BYREF | VT_VARIANT,VT_BYREF | VT_DISPATCH } };
__declspec(selectany) _ATL_FUNC_INFO XWebBrowser2EventsBase::OnQuitStruct = { CC_STDCALL, VT_EMPTY, 0, { NULL } };
__declspec(selectany) _ATL_FUNC_INFO XWebBrowser2EventsBase::OnVisibleStruct = { CC_STDCALL, VT_EMPTY, 1,{ VT_BOOL } };
__declspec(selectany) _ATL_FUNC_INFO XWebBrowser2EventsBase::QuitStruct = { CC_STDCALL, VT_EMPTY, 0,{ NULL } };
XEventSink::XEventSink(class XBrowser* a_pBrowser)
{
m_pBrowser = a_pBrowser;
}
XEventSink::~XEventSink()
{
UnAdvise();
}
void XEventSink::Advise()
{
if (FAILED(DispEventAdvise(m_pBrowser->m_pIE, &DIID_DWebBrowserEvents2)))
return;
OutputDebugString("Advise\n");
m_cnt = 0;
}
void XEventSink::UnAdvise()
{
DispEventUnadvise(m_pBrowser->m_pIE, &DIID_DWebBrowserEvents2);
OutputDebugString("UnAdvise\n");
}
READYSTATE XEventSink::GetReadyState()
{
READYSTATE state = READYSTATE_UNINITIALIZED;
if (m_pBrowser)
m_pBrowser->m_pIE->get_ReadyState(&state);
return state;
}
void XEventSink::OnBeforeNavigate2(IDispatch* pDisp, VARIANT* pvURL, VARIANT* pvFlags, VARIANT* pvTargetFrameName, VARIANT* pvPostData, VARIANT* pvHeaders, VARIANT_BOOL* pbCancel)
{
OutputDebugString(StringPrintf("OnBeforeNavigate2 %d\n", m_cnt++).c_str());
}
void XEventSink::OnDocumentComplete(IDispatch* pDisp, VARIANT* pvURL)
{
OutputDebugString(StringPrintf("OnDocumentComplete %d\n", m_cnt++).c_str());
if (GetReadyState() == READYSTATE_COMPLETE)
{
OutputDebugString("READYSTATE_COMPLETE\n");
m_pBrowser->WaitDocument();
}
}
void XEventSink::OnNavigateError(IDispatch* pDisp, VARIANT* pvURL, VARIANT* pvTargetFrameName, VARIANT* pvStatusCode, VARIANT_BOOL* pbCancel)
{
OutputDebugString(StringPrintf("OnNavigateError %d\n", m_cnt++).c_str());
}
void XEventSink::OnQuit()
{
OutputDebugString(StringPrintf("OnQuit %d\n", m_cnt++).c_str());
m_pBrowser->WaitDocument();
}
void XEventSink::OnVisible(VARIANT_BOOL bVisible)
{
OutputDebugString(StringPrintf("OnVisible %d\n", m_cnt++).c_str());
}
void XEventSink::Quit()
{
OutputDebugString(StringPrintf("Quit %d\n", m_cnt++).c_str());
}