Link to home
Start Free TrialLog in
Avatar of faster
faster

asked on

ActiveX

I need some sample code which can make use of events for an OLE automation object.  No MFC, ATL preferred.

Avatar of Tommy Hui
Tommy Hui

If you have Visual C++, take a look at the \vc\samples\atl\connect\drive directory, in the drive.cpp file. That shows you how to catch events using ATL. If you do not have the sample, here is the class:

class CDriver :
      public IDispatchImpl<IRandomEvent, &IID_IRandomEvent, &LIBID_CONNECTLib>,
      public CComObjectRoot
{
public:
      CDriver() {}
BEGIN_COM_MAP(CDriver)
      COM_INTERFACE_ENTRY(IDispatch)
      COM_INTERFACE_ENTRY(IRandomEvent)
END_COM_MAP()

// IRandomEvent
      STDMETHOD(Fire)(long l)
      {
            _tprintf(_T("%d\n"), l);
            return S_OK;
      }
};


Avatar of faster

ASKER

I will study the example.

There is another problem: if I set the atl project to use multithreaded dll, it give me link error (unresolved symbol), do you know why?
Avatar of faster

ASKER

I tried to catch events from IE auotmation object,  AtlAdvise completed ok but no event is trapped.  Can you see where is my problem?  I note that in exdisp.h, DWebBrowserEvents methods are commented, does this mean that I need to use some other interface?

Below is my code (modified based on drive.cpp)

// Drive.cpp : Implementation of WinMain
//
// This is a part of the Active Template Library.
// Copyright (C) 1996-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Active Template Library Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Active Template Library product.

// You will need the NT SUR Beta 2 SDK or VC 4.2 in order to build this
// project.  This is because you will need MIDL 3.00.15 or higher and new
// headers and libs.  If you have VC 4.2 installed, then everything should
// already be configured correctly.

#include "predrive.h"
#include "initguid.h"
#include "exdisp1.h"

//#define IID_DEFINED
#ifndef __IID_DEFINED__
#define __IID_DEFINED__

typedef struct _IID
{
    unsigned long x;
    unsigned short s1;
    unsigned short s2;
    unsigned char  c[8];
} IID;

#endif // __IID_DEFINED__

#ifndef CLSID_DEFINED
#define CLSID_DEFINED
typedef IID CLSID;
#endif

CComModule _Module;

/////////////////////////////////////////////////////////////////////////////
// CDriver

IID IID_DWebBrowserEvents = {0xEAB22AC2,0x30C1,0x11CF,{0xA7,0xEB,0x00,0x00,0xC0,0x5B,0xAE,0x0B}};
IID LIBID_DWebBrowserEvents = {0xEAB22AC0, 0x30C1, 0x11CF,{0xA7,0xEB,0x00,0x00,0xC0,0x5B,0xAE,0x0B}};
//const CLSID CLSID_InternetExplorer = {0x0002DF01,0x0000,0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
//const IID IID_IWebBrowserApp ={0x0002DF05,0x0000,0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};

class CDriver :
      public IDispatchImpl<DWebBrowserEvents, &IID_DWebBrowserEvents, &LIBID_DWebBrowserEvents>,
      public CComObjectRoot
{
public:
      CDriver() {}
BEGIN_COM_MAP(CDriver)
      COM_INTERFACE_ENTRY(IDispatch)
      COM_INTERFACE_ENTRY(DWebBrowserEvents)
END_COM_MAP()

      // DWebBrowserEvents
      void BeforeNavigate(BSTR URL, long Flags, BSTR TargetFrameName, VARIANT FAR* PostData, BSTR Headers, VARIANT_BOOL FAR* Cancel) {
            MessageBox(NULL, "BeforeNavigate","fired",MB_OK);
      };
      void NavigateComplete(BSTR URL) {};
      void StatusTextChange(BSTR Text) {};
      void ProgressChange(long Progress, long ProgressMax) {};
    void DownloadComplete(void) {};
    void CommandStateChange(long Command, VARIANT_BOOL Enable) {};
    void DownloadBegin(void) { };
    void NewWindow() {};
      void TitleChange(BSTR Text) {};
    void FrameBeforeNavigate(BSTR URL, long Flags, BSTR TargetFrameName, VARIANT FAR* PostData, BSTR Headers, VARIANT_BOOL FAR* Cancel) {};
    void FrameNavigateComplete(BSTR URL) {};
    void FrameNewWindow(BSTR URL, long Flags, BSTR TargetFrameName, VARIANT FAR* PostData, BSTR Headers, VARIANT_BOOL FAR* Processed) {};
    void Quit(VARIANT_BOOL FAR* Cancel) {};
    void WindowMove(void) {};
    void WindowResize(void) {};
    void WindowActivate(void) {};
    void PropertyChange(BSTR szProperty) {};
};

/////////////////////////////////////////////////////////////////////////////
//

extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
      LPTSTR lpCmdLine, int nShowCmd)
{
      HRESULT hRes = CoInitialize(NULL);
//  If you are running on NT 4.0 or higher you can use the following call
//  instead to make the EXE free threaded.
//  This means that calls come in on a random RPC thread
//  HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
      _Module.Init(NULL, hInstance);

      CComObject<CDriver>* pDriver;
      IWebBrowserApp* pM;
      CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_ALL, IID_IWebBrowserApp, (void**)&pM);

      CComObject<CDriver>::CreateInstance(&pDriver);
      DWORD dwAdvise = 0;
      hRes = AtlAdvise(pM, pDriver->GetUnknown(), IID_DWebBrowserEvents, &dwAdvise);

      pM->put_Visible(TRUE);

      MSG msg;
      while (GetMessage(&msg, 0, 0, 0))
            DispatchMessage(&msg);

      AtlUnadvise(pM, IID_DWebBrowserEvents, dwAdvise);

      pM->Release();

      CoUninitialize();
      return 0;
}

Avatar of faster

ASKER

I tried to catch events from IE auotmation object,  AtlAdvise completed ok but no event is trapped.  Can you see where is my problem?  I note that in exdisp.h, DWebBrowserEvents methods are commented, does this mean that I need to use some other interface?

Below is my code (modified based on drive.cpp)

// Drive.cpp : Implementation of WinMain
//
// This is a part of the Active Template Library.
// Copyright (C) 1996-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Active Template Library Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Active Template Library product.

// You will need the NT SUR Beta 2 SDK or VC 4.2 in order to build this
// project.  This is because you will need MIDL 3.00.15 or higher and new
// headers and libs.  If you have VC 4.2 installed, then everything should
// already be configured correctly.

#include "predrive.h"
#include "initguid.h"
#include "exdisp1.h"

//#define IID_DEFINED
#ifndef __IID_DEFINED__
#define __IID_DEFINED__

typedef struct _IID
{
    unsigned long x;
    unsigned short s1;
    unsigned short s2;
    unsigned char  c[8];
} IID;

#endif // __IID_DEFINED__

#ifndef CLSID_DEFINED
#define CLSID_DEFINED
typedef IID CLSID;
#endif

CComModule _Module;

/////////////////////////////////////////////////////////////////////////////
// CDriver

IID IID_DWebBrowserEvents = {0xEAB22AC2,0x30C1,0x11CF,{0xA7,0xEB,0x00,0x00,0xC0,0x5B,0xAE,0x0B}};
IID LIBID_DWebBrowserEvents = {0xEAB22AC0, 0x30C1, 0x11CF,{0xA7,0xEB,0x00,0x00,0xC0,0x5B,0xAE,0x0B}};
//const CLSID CLSID_InternetExplorer = {0x0002DF01,0x0000,0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
//const IID IID_IWebBrowserApp ={0x0002DF05,0x0000,0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};

class CDriver :
      public IDispatchImpl<DWebBrowserEvents, &IID_DWebBrowserEvents, &LIBID_DWebBrowserEvents>,
      public CComObjectRoot
{
public:
      CDriver() {}
BEGIN_COM_MAP(CDriver)
      COM_INTERFACE_ENTRY(IDispatch)
      COM_INTERFACE_ENTRY(DWebBrowserEvents)
END_COM_MAP()

      // DWebBrowserEvents
      void BeforeNavigate(BSTR URL, long Flags, BSTR TargetFrameName, VARIANT FAR* PostData, BSTR Headers, VARIANT_BOOL FAR* Cancel) {
            MessageBox(NULL, "BeforeNavigate","fired",MB_OK);
      };
      void NavigateComplete(BSTR URL) {};
      void StatusTextChange(BSTR Text) {};
      void ProgressChange(long Progress, long ProgressMax) {};
    void DownloadComplete(void) {};
    void CommandStateChange(long Command, VARIANT_BOOL Enable) {};
    void DownloadBegin(void) { };
    void NewWindow() {};
      void TitleChange(BSTR Text) {};
    void FrameBeforeNavigate(BSTR URL, long Flags, BSTR TargetFrameName, VARIANT FAR* PostData, BSTR Headers, VARIANT_BOOL FAR* Cancel) {};
    void FrameNavigateComplete(BSTR URL) {};
    void FrameNewWindow(BSTR URL, long Flags, BSTR TargetFrameName, VARIANT FAR* PostData, BSTR Headers, VARIANT_BOOL FAR* Processed) {};
    void Quit(VARIANT_BOOL FAR* Cancel) {};
    void WindowMove(void) {};
    void WindowResize(void) {};
    void WindowActivate(void) {};
    void PropertyChange(BSTR szProperty) {};
};

/////////////////////////////////////////////////////////////////////////////
//

extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
      LPTSTR lpCmdLine, int nShowCmd)
{
      HRESULT hRes = CoInitialize(NULL);
//  If you are running on NT 4.0 or higher you can use the following call
//  instead to make the EXE free threaded.
//  This means that calls come in on a random RPC thread
//  HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
      _Module.Init(NULL, hInstance);

      CComObject<CDriver>* pDriver;
      IWebBrowserApp* pM;
      CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_ALL, IID_IWebBrowserApp, (void**)&pM);

      CComObject<CDriver>::CreateInstance(&pDriver);
      DWORD dwAdvise = 0;
      hRes = AtlAdvise(pM, pDriver->GetUnknown(), IID_DWebBrowserEvents, &dwAdvise);

      pM->put_Visible(TRUE);

      MSG msg;
      while (GetMessage(&msg, 0, 0, 0))
            DispatchMessage(&msg);

      AtlUnadvise(pM, IID_DWebBrowserEvents, dwAdvise);

      pM->Release();

      CoUninitialize();
      return 0;
}

It seems that you are doing what the following article discusses.
http://www.microsoft.com/msj/0698/browser.htm

Download the code. There are samples in VB, MFC and ATL.
Avatar of faster

ASKER

Thanks Chensu, but the MFC example gave me some problem: whenever I click inside the WebConrtrol, it crashes.  This happens in the IDE only. Does it happen on your machine?

BTW, I did not find an installation program for internet client SDK, so I simply copied the include directory and lib directroy to VC, will that cause any problem?
>Does it happen on your machine?

No. It works fine.

>will that cause any problem?

Maybe. I remember there is an installation program for the Internet Client SDK. Why don't you use the latest Platform SDK which includes the Internet Client SDK?
Avatar of faster

ASKER

Which version of VC++ are you using?

I had Internet Client SDK, but didn't find any installation program.
Version 5.0. Try the latest Platform SDK.
Avatar of faster

ASKER

Is your VC with any patch?  And what is your OS?

"the latest Platform SDK", which one do you mean?  And you find a setup.exe for it?
>Is your VC with any patch?

Yes, Service Pack 3.

>And what is your OS?

I used Windows 95 to try that program.

>"the latest Platform SDK", which one do you mean?

I mean the Platform SDK September 1998 Edition that comes with MSDN CDs. Or you can download the Build Environment at http://msdn.microsoft.com/developer/sdk/bldenv.htm.

>And you find a setup.exe for it?

Yes.

Avatar of faster

ASKER

I found out that the crash is due to boundschecker, seems that boundschecker has some problem when debugging OLE applications.

You can submit an answer. Thanks.
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