웹, HTML

이벤트 싱크 소스 참조

디버그정 2009. 7. 5. 03:00
// ===========================================================================
// File: W I N S I N K . H
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright 1995-1999 Microsoft Corporation.  All Rights Reserved.
#ifndef _WinSink_h_
#define _WinSink_h_
#include
#include
#include
#include
class CWinSink : public IDispatch
{
public:
   
CWinSink() : m_pWin(NULL), m_dwRef(1),
            m_hrConnected
(CONNECT_E_CANNOTCONNECT),
            m_dwCookie
(0), m_pCP(NULL)
   
{
   
}
   
~CWinSink()
   
{
   
}
    HRESULT
Init(IHTMLElementPtr pWin);
    HRESULT
Passivate()
   
{
        HRESULT hr
= NOERROR;
       
if (m_pCP)
       
{
           
if (m_dwCookie)
           
{
                hr
= m_pCP->Unadvise(m_dwCookie);
                m_dwCookie
= 0;
           
}
             m_pCP
->Release();
             m_pCP
= NULL;
       
}
       
if (m_pWin)
       
{
            m_pWin
->Release();
            m_pWin
= NULL;
       
}
       
return NOERROR;
   
}
   
// IUnknown methods
    STDMETHOD
(QueryInterface)(REFIID riid, LPVOID* ppv);
    STDMETHOD_
(ULONG, AddRef)();
    STDMETHOD_
(ULONG, Release)();
   
// IDispatch method
    STDMETHOD
(GetTypeInfoCount)(UINT* pctinfo)
           
{ ODS("GetTypeInfoCount\n" ); return E_NOTIMPL; }
    STDMETHOD
(GetTypeInfo)(UINT iTInfo,
            LCID lcid
,
           
ITypeInfo** ppTInfo)
           
{ ODS("GetTypeInfo\n" ); return E_NOTIMPL; }
    STDMETHOD
(GetIDsOfNames)(REFIID riid,
            LPOLESTR
* rgszNames,
            UINT cNames
,
            LCID lcid
,
            DISPID
* rgDispId)
           
{ ODS("GetIDsOfNames\n" ); return E_NOTIMPL; }
       
    STDMETHOD
(Invoke)(DISPID dispIdMember,
            REFIID riid
,
            LCID lcid
,
            WORD wFlags
,
            DISPPARAMS __RPC_FAR
*pDispParams,
            VARIANT __RPC_FAR
*pVarResult,
            EXCEPINFO __RPC_FAR
*pExcepInfo,
            UINT __RPC_FAR
*puArgErr);
protected:
   
IHTMLElementPtr m_pWin;
    DWORD m_dwRef
;
    LPCONNECTIONPOINT m_pCP
;
    HRESULT m_hrConnected
;
    DWORD m_dwCookie
;
};
#endif

//===================
// ===========================================================================
// File: W I N S I N K . C P P
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
//
//    - CWinSink implements a simple object that traps MSHTML window events such as window::onload.
//    DHTML authors simply do the following in an HTML page:
//        function window_load()
//        {
//           alert("window::onload fired" );
//        }
//
//        window.onload = window_load;
//
//    C++ developers do the following:
//        Instantiate a host object that implements IDispatch
//        QI an interface exposed by MSHTML for IConnectionPointContainer (ICPC)
//        Request a specific connection point via ICPC
//        Call Advise on the connect point, passing a reference to the host object
//
//        MSHTML will call the host's IDispatch::Invoke implementation when an event occurs.
//  
//  - For a complete list of window events see dispinterface HTMLWindowEvents2 in mshtml.idl.
//
// Copyright 1995-1999 Microsoft Corporation.  All Rights Reserved.
#include "StdAfx.h"
//#include
#include
#include
#include "winsink.h"
#include
HRESULT
CWinSink::Init(IHTMLElementPtr pWin)
{
    HRESULT hr
= NOERROR;
    LPCONNECTIONPOINTCONTAINER pCPC
= NULL;
   
if (m_pWin)
   
{
        m_pWin
->Release();
   
}
    m_pWin
= pWin;
   
if (FAILED(hr = pWin->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pCPC)))
   
{
       
goto Error;
   
}
   
//if (FAILED(hr = pCPC->FindConnectionPoint(DIID_HTMLElementEvents2, &m_pCP)))
   
//if (FAILED(hr = pCPC->FindConnectionPoint(DIID_HTMLButtonElementEvents, &m_pCP)))
   
if (FAILED(hr = pCPC->FindConnectionPoint(DIID_HTMLAnchorEvents, &m_pCP)))
   
{
       
goto Error;
   
}
    m_hrConnected
= m_pCP->Advise((LPUNKNOWN)this, &m_dwCookie);
Error:
   
if (pCPC) pCPC->Release();
   
return hr;
}
STDMETHODIMP
CWinSink::QueryInterface(REFIID riid, LPVOID* ppv)
{
   
*ppv = NULL;
   
if (IID_IUnknown == riid)
   
{
       
*ppv = (LPUNKNOWN)this;
       
AddRef();
       
return NOERROR;
   
}
   
else if (IID_IDispatch == riid)
   
{
       
*ppv = (IDispatch*)this;
       
AddRef();
       
return NOERROR;
   
}
   
else
   
{
        OLECHAR wszBuff
[39];
       
int i = StringFromGUID2(riid, wszBuff, 39);
        TCHAR szBuff
[39];
        i
= WideCharToMultiByte(CP_ACP, 0, wszBuff, -1, szBuff, 39, NULL, NULL);
        ODS
("CWinSink QI: " ); ODS(szBuff); ODS("\n" );
       
return E_NOTIMPL;
   
}
}
STDMETHODIMP_
(ULONG) CWinSink::AddRef()
{
    TCHAR szBuff
[255];
    wsprintf
(szBuff, "CWinSink refcount increased to %d\n" , m_dwRef+1);
    ODS
(szBuff);
   
return ++m_dwRef;
}
STDMETHODIMP_
(ULONG) CWinSink::Release()
{
    TCHAR szBuff
[255];
   
if (--m_dwRef == 0)
   
{
        ODS
("Deleting CWinSink\n" );
       
delete this;
       
return 0;
   
}
    wsprintf
(szBuff, "CWinSink refcount reduced to %d\n" , m_dwRef);
    ODS
(szBuff);
   
return m_dwRef;
}
// OA events are fired through the IDispatch::Invoke of the sink object
STDMETHODIMP
CWinSink::Invoke(DISPID dispIdMember,
            REFIID riid
,
            LCID lcid
,
            WORD wFlags
,
            DISPPARAMS __RPC_FAR
*pDispParams,
            VARIANT __RPC_FAR
*pVarResult,
            EXCEPINFO __RPC_FAR
*pExcepInfo,
            UINT __RPC_FAR
*puArgErr)
{
   
if (!pVarResult)
   
{
       
return E_POINTER;
   
}
   
if( pDispParams->cArgs != 0 )
       
IHTMLEventObjPtr pEvtObj = pDispParams->rgvarg[0].pdispVal;
   
switch(dispIdMember)
   
{
   
case DISPID_HTMLELEMENTEVENTS_ONCLICK:
       
{
       
/*
            IHTMLEventObjPtr pEvtObj = pDispParams->rgvarg[0].pdispVal;
        IHTMLElementPtr pElem;
        pEvtObj->get_srcElement(&pElem);
        pElem->toString( &bstStr );
        */

        BSTR bstStr
;
        m_pWin
->toString(&bstStr);
       
        _bstr_t bsStr
(bstStr);
       
MessageBox(NULL,"OnClick" ,(LPCTSTR)bsStr,MB_OK);
       
}
       
break;
   
default:
       
return DISP_E_MEMBERNOTFOUND;
   
}
   
return NOERROR;
}
//===================

#include
#include
#include "winsink.h"
void CTestEventIEDlg::OnSink()
{
   
// TODO: Add your control notification handler code here
   
//CWebBrowser2* pBrowser = (CWebBrowser2*)GetDlgItem( IDC_EXPLORER1 );
   
   
IDispatchPtr pDisp = m_web.GetDocument();
   
if (pDisp != NULL )
   
{
        IHTMLDocument2Ptr pHTMLDocument2
;
        HRESULT hr
;
        hr
= pDisp->QueryInterface( IID_IHTMLDocument2, (void**)&pHTMLDocument2 );
       
if (hr == S_OK)
       
{
           
IHTMLElementCollectionPtr pColl;
            hr
= pHTMLDocument2->get_all( &pColl );
           
if (hr == S_OK)
           
{
                VARIANT varIndex
;
                varIndex
.vt = VT_BSTR;
                varIndex
.bstrVal = _bstr_t("item1" );
                VARIANT var2
;
               
VariantInit( &var2 );
               
IDispatch* pDisp;
                hr
= pColl->item( varIndex, var2, &pDisp );
               
if ( hr == S_OK )
               
{
                   
IHTMLElementPtr pElem;
                    hr
= pDisp->QueryInterface( IID_IHTMLElement, (void **)&pElem );
                   
if ( hr == S_OK )
                   
{
                        m_sink
.Init(pElem);
                   
}
               
}
           
}
       
}
   
}
   
}