/*
#define DISPID_BEFORENAVIGATE2 250 // hyperlink clicked on
#define DISPID_NEWWINDOW2 251
#define DISPID_NAVIGATECOMPLETE2 252 // UIActivate new document
#define DISPID_ONQUIT 253
#define DISPID_ONVISIBLE 254 // sent when the window goes visible/hidden
#define DISPID_ONTOOLBAR 255 // sent when the toolbar should be shown/hidden
#define DISPID_ONMENUBAR 256 // sent when the menubar should be shown/hidden
#define DISPID_ONSTATUSBAR 257 // sent when the statusbar should be shown/hidden
#define DISPID_ONFULLSCREEN 258 // sent when kiosk mode should be on/off
#define DISPID_DOCUMENTCOMPLETE 259 // new document goes ReadyState_Complete
#define DISPID_ONTHEATERMODE 260 // sent when theater mode should be on/off
#define DISPID_ONADDRESSBAR 261 // sent when the address bar should be shown/hidden
#define DISPID_WINDOWSETRESIZABLE 262 // sent to set the style of the host window frame
#define DISPID_WINDOWCLOSING 263 // sent before script window.close closes the window
#define DISPID_WINDOWSETLEFT 264 // sent when the put_left method is called on the WebOC
#define DISPID_WINDOWSETTOP 265 // sent when the put_top method is called on the WebOC
#define DISPID_WINDOWSETWIDTH 266 // sent when the put_width method is called on the WebOC
#define DISPID_WINDOWSETHEIGHT 267 // sent when the put_height method is called on the WebOC
#define DISPID_CLIENTTOHOSTWINDOW 268 // sent during window.open to request conversion of dimensions
#define DISPID_SETSECURELOCKICON 269 // sent to suggest the appropriate security icon to show
#define DISPID_FILEDOWNLOAD 270 // Fired to indicate the File Download dialog is opening
#define DISPID_NAVIGATEERROR 271 // Fired to indicate the a binding error has occured
#define DISPID_PRIVACYIMPACTEDSTATECHANGE 272 // Fired when the user's browsing experience is impacted
*/
// convert CString to a COleVariant
COleVariant vaURL(strURL);
// we need to add 1 to the counter because we are calling Navigate2()
// therefore BeforeNavigate2() will not be called
m_nPageCounter ++;
m_nObjCounter ++;
// advise the browser to send events here
LPUNKNOWN pUnkSink = GetIDispatch(FALSE);
AfxConnectionAdvise((LPUNKNOWN)m_pWebBrowser2,DIID_DWebBrowserEvents2,pUnkSink,FALSE,&m_dwCookie);
/*
or
// Retrieve and store the IConnectionPointerContainer pointer
spCPC = spWebBrowser2;
if (spCPC == NULL)
return E_POINTER;
// Receives the connection point for WebBrowser events
hr = spCPC->FindConnectionPoint(DIID_DWebBrowserEvents2, &spCP);
if (FAILED(hr))
return hr;
// Pass our event handlers to the container. Each time an event occurs
// the container will invoke the functions of the IDispatch interface
// we implemented.
hr = spCP->Advise(reinterpret_cast<IDispatch*>(this),&dwCookie);
...
AfxConnectionUnadvise((LPUNKNOWN)m_pWebBrowser2, DIID_DWebBrowserEvents2, pUnkSink, FALSE, m_dwCookie);
*/
class CIEComCtrlSink : public CCmdTarget
{
DECLARE_DYNCREATE(CIEComCtrlSink)
...
// Fires before a navigation occurs in the given object
afx_msg void BeforeNavigate2(LPDISPATCH pDisp, VARIANT FAR *url, VARIANT FAR *Flags, VARIANT FAR *TargetFrameName, VARIANT FAR *PostData, VARIANT FAR *Headers, VARIANT_BOOL* Cancel);
// Fires when the document that is being navigated to reaches the READYSTATE_COMPLETE state
afx_msg void DocumentComplete(IDispatch *pDisp,VARIANT *URL);
// Fires when a navigation operation is beginning.
afx_msg void DownloadBegin();
// Fires when a navigation operation finishes, is halted, or fails.
afx_msg void DownloadEnd();
// browser is quiting so kill events
afx_msg void OnQuit();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CIEComCtrlSink)
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CIEComCtrlSink)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
CIEComCtrlSink::CIEComCtrlSink()
{
// enable OLE
EnableAutomation();
...
}
...
// using MFC CCmdTarget to catch DWebBrowserEvents2 events
BEGIN_MESSAGE_MAP(CIEComCtrlSink, CCmdTarget)
//{{AFX_MSG_MAP(CIEComCtrlSink)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// these are the events we want to monitor.
// The events are explained below above their function implementations.
BEGIN_DISPATCH_MAP(CIEComCtrlSink, CCmdTarget)
DISP_FUNCTION_ID(CIEComCtrlSink, "OnQuit",DISPID_ONQUIT,OnQuit,VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CIEComCtrlSink, "BeforeNavigate2",DISPID_BEFORENAVIGATE2,BeforeNavigate2,
VT_EMPTY, VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)
DISP_FUNCTION_ID(CIEComCtrlSink, "DocumentComplete",DISPID_DOCUMENTCOMPLETE,DocumentComplete,
VT_EMPTY, VTS_DISPATCH VTS_PVARIANT)
DISP_FUNCTION_ID(CIEComCtrlSink, "DownloadBegin",DISPID_DOWNLOADBEGIN,DownloadBegin,VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CIEComCtrlSink, "DownloadEnd",DISPID_DOWNLOADCOMPLETE,DownloadEnd,VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()
...
// browser is quiting so kill events
void CIEComCtrlSink::OnQuit()
{
UnAdviseSink();
}
// Fires before a navigation occurs in the given object
void CIEComCtrlSink::BeforeNavigate2(LPDISPATCH pDisp, VARIANT FAR *url, VARIANT FAR *Flags,
VARIANT FAR *TargetFrameName, VARIANT FAR *PostData, VARIANT FAR *Headers, VARIANT_BOOL* Cancel)
{
...
// capture relevant information on the URL etc we are about to load.
CString strHeaders = (BSTR)Headers->bstrVal;
CString strUrl = (BSTR)url->bstrVal;
CString strPostData;
// do we have post data?
if (PostData != NULL && PostData->vt == (VT_VARIANT|VT_BYREF) && PostData->pvarVal->vt != VT_EMPTY )
{
char *szTemp = NULL, *szPostData = NULL;
long plLbound, plUbound;
// get web browser Dispatch to see if this is the top level URL call
LPDISPATCH lpWBDisp;
m_pWebBrowser2->QueryInterface(IID_IDispatch, (void**)&lpWBDisp);
if (pDisp == lpWBDisp && !m_bIsRefresh)
{
// Top-level Window object, so store URL for a refresh request
m_strHeaders = strHeaders;
m_strUrl = strUrl;
m_strPostData = strPostData;
...
}
lpWBDisp->Release();
}
// Fires when the document that is being navigated to reaches the READYSTATE_COMPLETE state
void CIEComCtrlSink::DocumentComplete(IDispatch *pDisp,VARIANT *URL)
{
...
CString strURL = (BSTR)URL->bstrVal;
// get web browser Dispatch to see if this is the top level URL call
LPDISPATCH lpWBDisp;
m_pWebBrowser2->QueryInterface(IID_IDispatch, (void**)&lpWBDisp);
if (pDisp == lpWBDisp )
{
// Top-level Window object, so document has been loaded
// have our parent class use this information in some way....
m_pParent->DisplayDocComplete(strURL);
}
lpWBDisp->Release();
}
// Fires when a navigation operation is beginning.
void CIEComCtrlSink::DownloadBegin()
{
...
}
// Fires when a navigation operation finishes, is halted, or fails.
void CIEComCtrlSink::DownloadEnd()
{
...
}
/*
or
class ATL_NO_VTABLE CBhoApp :
...
public IDispatchImpl<IBhoApp, &IID_IBhoApp, &LIBID_BHONEWLib>
{
public:
CBhoApp()
{
}
STDMETHODIMP CBhoApp::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pvarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
USES_CONVERSION; // This macro should be called when using ATL string conversion
// macros to avoid compile errors (here we are using OLE2T)