Как обработать событие DocumentCompleted от IWebBrowser2 в консольном приложении ?

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Executer
Сообщения: 2
Зарегистрирован: 22 май 2016, 20:55

16 мар 2017, 19:46

Добрый день!
Есть консольное приложение, необходимо поймать событие DocumentCompleted которое отправит IWebBrowser2 после загрузки страницы и проверить что IWebBrowser2.ReadyState имеет READYSTATE_COMPLETE. В COM к сожалению не разбираюсь, можно хотя бы ссылку с примером подобного.

Код: Выделить всё

#include <mshtml.h>
#include <exdisp.h>

void test()
{
   if (SUCCEEDED(OleInitialize(NULL)))
   {
      IWebBrowser2*    pBrowser2;

      CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER,
         IID_IWebBrowser2, (void**)&pBrowser2);
      if (pBrowser2)
      {
         VARIANT vEmpty;
         VariantInit(&vEmpty);

         VARIANT vFlags;
         V_VT(&vFlags) = VT_I4;
         V_I4(&vFlags) = navOpenInNewWindow;

         BSTR bstrURL = SysAllocString(L"http://forum.developing.ru");
         HRESULT hState = pBrowser2->Navigate(bstrURL, &vFlags, &vEmpty, &vEmpty, &vEmpty);
         READYSTATE ReadyState;
         if (SUCCEEDED(hState))
         {
            pBrowser2->put_Visible(VARIANT_TRUE);
            if (SUCCEEDED(pBrowser2->get_ReadyState(&ReadyState)))
            {
               do //цилк полная фигня и дождаться что ReadyState будет READYSTATE_COMPLETE             невозможно, то есть он бесконечный.
               {
                  pBrowser2->get_ReadyState(&ReadyState);
               } 
               while (ReadyState != READYSTATE_COMPLETE);
            }
            std::cout << "READYSTATE_COMPLETE" << std::endl;
         }

         pBrowser2->Quit();

         SysFreeString(bstrURL);
         pBrowser2->Release();
      }
   }
}

int main()
{
   test();
   return 0;
}
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

16 мар 2017, 23:54

Браузер-то открывается? При выполнении этого кода должен открыться браузер в отдельном окне. Если не открылся, значит проблема не в ReadyState.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Executer
Сообщения: 2
Зарегистрирован: 22 май 2016, 20:55

17 мар 2017, 01:22

Romeo писал(а):Браузер-то открывается? При выполнении этого кода должен открыться браузер в отдельном окне. Если не открылся, значит проблема не в ReadyState.
Браузер открывается.
Нашел на MSDN https://msdn.microsoft.com/en-us/librar ... s.85).aspx и https://msdn.microsoft.com/en-us/librar ... s.85).aspx но не могу понять как это правильно использовать.
Executer
Сообщения: 2
Зарегистрирован: 22 май 2016, 20:55

22 мар 2017, 23:44

Вообщем нашел пример, вдруг кому то пригодится.

Код: Выделить всё

    #include <iostream>
    #include "Exdisp.h"
    #include "Exdispid.h"
    #include <Mshtml.h>
    #include "atlbase.h"
    #include "Windows.h"
    #include "mshtmdid.h"
     
    class THtmlEventSink : public IDispatch
    {
    protected:
        long m_cRef;
    public:
        THtmlEventSink() { m_cRef = 0; }
        ~THtmlEventSink() { }
     
        HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject)
        {
            *ppvObject = NULL;
     
            if (IsEqualGUID(riid, IID_IUnknown))
                *ppvObject = reinterpret_cast<void**>(this);
     
            if (IsEqualGUID(riid, IID_IDispatch))
                *ppvObject = reinterpret_cast<void**>(this);
     
            if (*ppvObject)
            {
                ((IUnknown*)*ppvObject)->AddRef();
                return S_OK;
            }
            else return E_NOINTERFACE;
        }
     
        DWORD __stdcall AddRef()
        {
            return InterlockedIncrement(&m_cRef);
        }
     
        DWORD __stdcall Release()
        {
            if (InterlockedDecrement(&m_cRef) == 0)
            {
                delete this;
                return 0;
            }
            return m_cRef;
        }
     
        STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pctinfo)
        {
            return E_NOTIMPL;
        }
     
        STDMETHOD(GetTypeInfo)(unsigned int iTInfo, LCID  lcid, ITypeInfo FAR* FAR*  ppTInfo)
        {
            return E_NOTIMPL;
        }
     
        STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgDispId)
        {
            return S_OK;
        }
     
        STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr)
        {
            if (dispIdMember == DISPID_DOCUMENTCOMPLETE)
            {
                HRESULT hr;
                CComQIPtr<IDispatch> disp = ((*pDispParams).rgvarg)[1].pdispVal;
                CComPtr<IWebBrowser2> browser;
                hr = disp->QueryInterface(IID_IWebBrowser2, (void**)&browser);
                READYSTATE state;
                hr = browser->get_ReadyState(&state);
                if (state == READYSTATE_COMPLETE)
                {
                    std::cout << "DocumentComplete Event with state READYSTATE_COMPLETE" << std::endl;
                }
            }
            return S_OK;
        }
    };
     
     
     
    int main()
    {
        HRESULT hr;
        IWebBrowser2* pBrowser2;
        if (SUCCEEDED(OleInitialize(NULL)))
        {
            CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (void**)&pBrowser2);
            if (pBrowser2)
            {
                /**
               *
               */
                IConnectionPointContainer* pCPC = NULL;
                IConnectionPoint* pCP = NULL;
                DWORD dwCookie;
                THtmlEventSink* pUnk = new THtmlEventSink;
     
                hr = pBrowser2->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
                if (SUCCEEDED(hr))
                {
                    std::cout << "ConnectionPointContainer ok!\n";
     
                    hr = pCPC->FindConnectionPoint(DIID_DWebBrowserEvents2, &pCP);
                    if (SUCCEEDED(hr))
                    {
                        std::cout << "FindConnectionPoint DIID_DWebBrowserEvents2 ok!\n";
                        hr = pCP->Advise(pUnk, &dwCookie);
                        if (SUCCEEDED(hr))
                        {
                            std::cout << "Event succes!\n";
                        }
                    }
                }
     
                VARIANT vEmpty;
                VariantInit(&vEmpty);
                BSTR bstrURL = SysAllocString(L"http://ixbt.com");
                hr = pBrowser2->Navigate(bstrURL, &vEmpty, &vEmpty, &vEmpty, &vEmpty);
     
                if (SUCCEEDED(hr))
                {
                    pBrowser2->put_Visible(VARIANT_TRUE);
                }
                else
                {
                    pBrowser2->Quit();
                }
            }
        }
     
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        OleUninitialize();
     
        std::cin.get();
     
        return 0;
    }
Ответить