Link to home
Start Free TrialLog in
Avatar of balshetzer
balshetzer

asked on

Receiving events from Internet Explorer

I am trying to use IE programmatically to do some web mining. I'm more
of a Java coder. I've never used COM, ATL or MFC before so I am a
little overwhelmed by the sheer amount of info I had to read just to
interface with the browser.

I wrote the following code as a test to open a browser window and
receive a single event (DocumentComplete) with the intention of then
retrieving the content and working with it.

However, when I run the code it opens a browser window, which hangs
until the event handler is unregistered at which point the page loads.
I don't understand this behavior. It only happens when I try to
connect an event handler.

Maybe I am making some kind of fundamental error. I have tried to
simplify the code as much as possible removing all attempts to use
ATL. I'd prefer not to have to learn MFC right now.

Here is the cpp file:
#include <stdio.h>
#include "header.h"

void EventHandler::DocumentComplete(IDispatch *pDisp, VARIANT *URL) {
   printf("event triggered");
}

int main(int argc, char* argv[])
{
   CoInitialize(NULL);

   SHDocVw::IWebBrowser2Ptr ie;
   ie.CreateInstance("InternetExplorer.Application");
   
   EventHandler handler;

   IUnknown *pUnk = NULL;
   IUnknown *pHandler = NULL;
   
   DWORD dwCookie;

   HRESULT hr;
   
   hr = handler.QueryInterface(IID_IUnknown, (void**)&pHandler);
   
   hr = ie.QueryInterface(IID_IUnknown, &pUnk);
   
   IConnectionPointContainer* pCPC = NULL;
   IConnectionPoint* pCP = NULL;
   
   // Check that this is a connectable object.
   hr = pUnk->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
   
   if (SUCCEEDED(hr))
   {
      // Find the connection point.
      hr = pCPC->FindConnectionPoint(DIID_DWebBrowserEvents2, &pCP);
     
      if (SUCCEEDED(hr))
      {
         // Advise the connection point.
         hr = pCP->Advise(pHandler, &dwCookie);
         
         if (SUCCEEDED(hr))
         {
            printf("advised\n");
         }
      }
     
      pCPC->Release();
   }

   pUnk->Release();

   ie->Visible = true;
   ie->Navigate("www.microsoft.com");

   Sleep(5000);

   pCP->Unadvise(dwCookie);
   pCP->Release();
   // only at this point does the browser window "unhang"

   ie.Release();
   CoUninitialize();



      printf("done\n");
      return 0;
}

here is header.h (the commented out section was the simple way to
implement the handler. The uncommented is the long way. The stubs look
odd because they are copied out of the header file.):

#ifndef _COMMSTUFF_H
#define _COMMSTUFF_H

#import "shdocvw.dll"

#include <exdisp.h>    // browser control definitions
#include <exdispid.h>  // browser event dispatch IDs

/*
class EventHandler : public IDispEventImpl<1, EventHandler,
&DIID_DWebBrowserEvents2, &LIBID_SHDocVw>
{

public:

   BEGIN_SINK_MAP(EventHandler)
      SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2,
DISPID_DOCUMENTCOMPLETE, DocumentComplete)
   END_SINK_MAP()

   void _stdcall DocumentComplete(LPDISPATCH pDisp, VARIANT* URL);



};
*/

class EventHandler : public DWebBrowserEvents2
{
public:

   // IUnknown
   virtual HRESULT STDMETHODCALLTYPE QueryInterface(
      /* [in] */ REFIID riid,
      /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
   {
      if (riid == IID_IUnknown || riid == IID_IDispatch || riid ==
DIID_DWebBrowserEvents2)
      {
         *ppvObject = (void*)this;
         return S_OK;
      }
      return E_NOINTERFACE;
   }
       
   virtual ULONG STDMETHODCALLTYPE AddRef() { return 1L; }
       
   virtual ULONG STDMETHODCALLTYPE Release() { return 1L; }

   // IDispatch
   virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(
   /* [out] */ UINT __RPC_FAR *pctinfo)
      { return E_NOTIMPL; }
       
   virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(
      /* [in] */ UINT iTInfo,
      /* [in] */ LCID lcid,
      /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
      { return E_NOTIMPL; }
       
   virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(
      /* [in] */ REFIID riid,
      /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
      /* [in] */ UINT cNames,
      /* [in] */ LCID lcid,
      /* [size_is][out] */ DISPID __RPC_FAR *rgDispId)
      { return E_NOTIMPL; }
       
   virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(
      /* [in] */ DISPID dispIdMember,
      /* [in] */ REFIID riid,
      /* [in] */ LCID lcid,
      /* [in] */ WORD wFlags,
      /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
      /* [out] */ VARIANT __RPC_FAR *pVarResult,
      /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
      /* [out] */ UINT __RPC_FAR *puArgErr)
      { return E_NOTIMPL; }


    void StatusTextChange (
       _bstr_t Text ){}
    void ProgressChange (
        long Progress,
        long ProgressMax ){}
    void CommandStateChange (
        long Command,
        VARIANT_BOOL Enable ){}
    void DownloadBegin ( ){}
    void DownloadComplete ( ){}
    void TitleChange (
        _bstr_t Text ){}
    void PropertyChange (
        _bstr_t szProperty ){}
    void BeforeNavigate2 (
        IDispatch * pDisp,
        VARIANT * URL,
        VARIANT * Flags,
        VARIANT * TargetFrameName,
        VARIANT * PostData,
        VARIANT * Headers,
        VARIANT_BOOL * Cancel ){}
    void NewWindow2 (
        IDispatch * * ppDisp,
        VARIANT_BOOL * Cancel ){}
    void NavigateComplete2 (
        IDispatch * pDisp,
        VARIANT * URL ){}
    void DocumentComplete (
        IDispatch * pDisp,
        VARIANT * URL );
    void OnQuit ( ){}
    void OnVisible (
       VARIANT_BOOL Visible ){ }
    void OnToolBar (
        VARIANT_BOOL ToolBar ){}
    void OnMenuBar (
        VARIANT_BOOL MenuBar ){}
    void OnStatusBar (
        VARIANT_BOOL StatusBar ){}
    void OnFullScreen (
        VARIANT_BOOL FullScreen ){}
    void OnTheaterMode (
        VARIANT_BOOL TheaterMode ){}
    void WindowSetResizable (
        VARIANT_BOOL Resizable ){}
    void WindowSetLeft (
        long Left ){}
    void WindowSetTop (
        long Top ){}
    void WindowSetWidth (
        long Width ){}
    void WindowSetHeight (
        long Height ){}
    void WindowClosing (
        VARIANT_BOOL IsChildWindow,
        VARIANT_BOOL * Cancel ){}
    void ClientToHostWindow (
        long * CX,
        long * CY ){}
    void SetSecureLockIcon (
        long SecureLockIcon ){}
    void FileDownload (
        VARIANT_BOOL * Cancel ){}
    void NavigateError (
        IDispatch * pDisp,
        VARIANT * URL,
        VARIANT * Frame,
        VARIANT * StatusCode,
        VARIANT_BOOL * Cancel ){}
    void PrintTemplateInstantiation (
        IDispatch * pDisp ){}
    void PrintTemplateTeardown (
        IDispatch * pDisp ){}
    void UpdatePageStatus (
        IDispatch * pDisp,
        VARIANT * nPage,
        VARIANT * fDone ){}
    void PrivacyImpactedStateChange (
        VARIANT_BOOL bImpacted ){}

};



#endif
ASKER CERTIFIED SOLUTION
Avatar of chensu
chensu
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of millsoft
millsoft

Concur with Chensu.

Have you considered simply opening a connection to the desired URL on Port 80 using Sockets instead of trying to embed IE?  It seems easier.

Embedding IE is pretty easy if you use Visual C++ (If you have it) .  Create an application with AppWizard and use Class Wizard to "add a class" and select the SHDOCVIEW.DLL and it reads the embedded type library.

Avatar of balshetzer

ASKER

thanks for your help.
The reason I am using IE instead of http over sockets is to let IE handle scripting/cookies for me