IWebBrowser2 DISPID_QUIT
От: flonder  
Дата: 26.07.17 14:48
Оценка:
Цепляюсь к запущенному 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());
}
Отредактировано 26.07.2017 14:56 flonder . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.