Figure 2
Figure 2 COM Interface Methods| IElementalBehavior | |
| Method | Description |
| Detach | Informs the behavior that it is being detached from the element |
| Init | Informs the behavior that it's been created |
| Notify | Notifies the behavior about the various stages in the initialization of both the host document and the attached element |
| IElementBehaviorFactory | |
| Method | Description |
| FindBehavior | Instantiates the specified behavior |
| IElementBehaviorCategory (optional) | |
| Method | Description |
| GetCategory | Returns the string with the name of the category that the behavior belongs to |
| IElementBehaviorRender (optional and obsolete in Internet Explorer 5.5) | |
| Method | Description |
| Draw | Invoked to draw the user interface for the behavior |
| GetRenderInfo | Retrieves rendering information for the behavior |
| HitTestPoint | Indicates whether the specified point is contained in the behavior's area |
<PUBLIC:HTC>
<PUBLIC:ATTACH event="onmouseover"
handler="fnOver"/>
<PUBLIC:ATTACH event="onmouseout"
handler="fnOut"/>
<script LANGUAGE="jscript">
function fnOver()
{element.style.color="red";}
function fnOut()
{element.style.color="";}
</script>
</PUBLIC:HTC>
Figure 4 Binary Mouseover Behavior in C++ // Behavior.h : Declaration of the CBehavior
#ifndef __BEHAVIOR_H_
#define __BEHAVIOR_H_
#include "resource.h" // main symbols
#include "IElementBehaviorImpl.h" // IElementBehavior
#include "DHTMLEvents.h" //
/////////////////////////////////////////////////////////////////////////////
// CBehavior
class ATL_NO_VTABLE CBehavior :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CBehavior, &CLSID_Behavior>,
public IElementBehaviorImpl,
public IDispatchImpl<IBehavior, &IID_IBehavior, &LIBID_MYBEHLib>
{
public:
CBehavior()
{
m_pEventSink = NULL;
m_dwCookie = 0;
}
DECLARE_REGISTRY_RESOURCEID(IDR_BEHAVIOR)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CBehavior)
COM_INTERFACE_ENTRY(IElementBehavior)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// IElementBehavior
public:
STDMETHOD(Notify)(LONG lEvent, VARIANT *pVar);
STDMETHOD(Init)(IElementBehaviorSite *pBehaviorSite);
STDMETHOD(Detach)(void);
CComPtr<IHTMLElement> m_spElem;
CComVariant m_oldColor;
private:
CComPtr<IElementBehaviorSite> m_spSite;
CComObject<CDHTMLEvents>* m_pEventSink;
DWORD m_dwCookie;
};
#endif //__BEHAVIOR_H_
///////////////////////////////////////////////////////////////////////////
// Factory.h : Declaration of the CFactory
#ifndef __FACTORY_H_
#define __FACTORY_H_
#include "resource.h" // main symbols
#include "behavior.h" // IElementBehavior
/////////////////////////////////////////////////////////////////////////////
// CFactory
class ATL_NO_VTABLE CFactory :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CFactory, &CLSID_Factory>,
public IObjectSafetyImpl<CFactory,INTERFACESAFE_FOR_UNTRUSTED_CALLER>,
public IElementBehaviorFactory
{
public:
CFactory()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_FACTORY)
BEGIN_COM_MAP(CFactory)
COM_INTERFACE_ENTRY(IElementBehaviorFactory)
COM_INTERFACE_ENTRY(IObjectSafety)
END_COM_MAP()
// IFactory
public:
STDMETHOD(FindBehavior)(BSTR bstrBehavior,
BSTR bstrBehaviorUrl,
IElementBehaviorSite* pSite,
IElementBehavior** ppBehavior);
// IObjectSafety override
STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid,
DWORD dwOptionSetMask, DWORD dwEnabledOptions)
{
// Set the safety options we have been asked to set.
m_dwCurrentSafety = m_dwCurrentSafety & ~dwEnabledOptions |
dwOptionSetMask;
return S_OK;
}
};
#endif //__FACTORY_H_
///////////////////////////////////////////////////////////////////
Figure 5 Sink Object // DHTMLEvents.h : Declaration of the CDHTMLEvents
#ifndef __DHTMLEVENTS_H_
#define __DHTMLEVENTS_H_
#include "resource.h" // main symbols
#include <mshtmdid.h> // DHTML Behavior identifiers
#include <mshtmhst.h> // DHTML Behavior interfaces
#include <mshtml.h> // DHTML Object model
/////////////////////////////////////////////////////////////////////////////
// CDHTMLEvents
class CBehavior;
class ATL_NO_VTABLE CDHTMLEvents :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CDHTMLEvents, &CLSID_DHTMLEvents>,
public IDispatchImpl<IDHTMLEvents, &IID_IDHTMLEvents, &LIBID_MYBEHLib>
{
public:
CDHTMLEvents()
{
m_pBehavior = NULL;
}
DECLARE_REGISTRY_RESOURCEID(IDR_DHTMLEVENTS)
DECLARE_NOT_AGGREGATABLE(CDHTMLEvents)
//DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CDHTMLEvents)
COM_INTERFACE_ENTRY2(HTMLElementEvents, IDHTMLEvents)
COM_INTERFACE_ENTRY2(HTMLAnchorEvents, IDHTMLEvents)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IDHTMLEvents)
END_COM_MAP()
// IDispatchImpl override
STDMETHOD(Invoke)(DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pdispparams,
VARIANT* pvarResult,
EXCEPINFO* pexcepinfo,
UINT* puArgErr);
// Event Handlers (cfr. <PUBLIC:ATTACH>)
public:
void OnMouseOver();
void OnMouseOut();
// data members
CBehavior *m_pBehavior;
};
#endif //__DHTMLEVENTS_H_
Figure 6 Implementation of the Behavior Behavior.cpp
// Behavior.cpp : Implementation of CBehavior
#include "stdafx.h"
#include "MyBeh.h"
#include "DHTMLEvents.h"
#include "Behavior.h"
/////////////////////////////////////////////////////////////////////////////
// CBehavior
//////////////////////////////////////////////////////////////////////
// Init()
HRESULT CBehavior::Init(IElementBehaviorSite *pBehaviorSite)
{
// Cache the IElementBehaviorSite interface pointer
m_spSite = pBehaviorSite;
return S_OK;
}
//////////////////////////////////////////////////////////////////////
// Notify()
HRESULT CBehavior::Notify(LONG lEvent, VARIANT *pVar)
{
// What happens here is equivalent to <PUBLIC:ATTACH> for
// oncontentready and ondocumentready
switch(lEvent)
{
case BEHAVIOREVENT_CONTENTREADY:
m_spSite->GetElement(&m_spElem);
// Do something
break;
case BEHAVIOREVENT_DOCUMENTREADY:
m_spSite->GetElement(&m_spElem);
// Do something
break;
}
return S_OK;
}
//////////////////////////////////////////////////////////////////////
// Detach()
HRESULT CBehavior::Detach(void)
{
if (m_spElem)
m_spElem.Release();
return S_OK;
}
Factory.cpp // Factory.cpp : Implementation of CFactory
#include "stdafx.h"
#include "MyBeh.h"
#include "Factory.h"
/////////////////////////////////////////////////////////////////////////////
// CFactory
HRESULT CFactory::FindBehavior(BSTR bstrBehavior, BSTR bstrBehaviorUrl,
IElementBehaviorSite *pSite, IElementBehavior **ppBehavior)
{
CComObject<CBehavior>* pBehavior;
// Create a Behavior object
HRESULT hr = CComObject<CBehavior>::CreateInstance(&pBehavior);
if (SUCCEEDED(hr))
hr = pBehavior->QueryInterface(__uuidof(IElementBehavior),
(void**)ppBehavior);
return hr;
}
Figure 7 Tags and Their COM Equivalents | HTC Tag | COM Equivalent |
| <PUBLIC:ATTACH event="oncontentready" /> <PUBLIC:ATTACH event="ondocumentready" /> | IElementBehavior::Notify |
| <PUBLIC:ATTACH event="Any DHTML Event" /> | Sink object exposing IDispatch |
| <PUBLIC:PROPERTY name="Property"> | IDispatch on behavior's coclass |
| <PUBLIC:METHOD name="Method"> | IDispatch on behavior's coclass |
| <PUBLIC:EVENT name="Event"> | Methods of IElementBehaviorSiteOM |
| addBehavior or behavior CSS | IElementBehaviorFactory |
| removeBehavior | IElementBehavior::Detach |
if (m_spSiteOM)
{
LONG cookie;
HRESULT hr;
hr = m_spSiteOM->GetEventCookie(L"oninitcomplete", &cookie);
if (SUCCEEDED(hr))
{
IHTMLEventObject* pEvent;
hr = m_spSiteOM->CreateEventObject(&pEvent);
if (SUCCEEDED(hr))
{
m_spSiteOM->FireEvent(cookie, pEvent);
pEvent->Release();
}
}
}
Figure 9 Sinking DHTML Events // DHTMLEvents.h : Declaration of the CDHTMLEvents
#ifndef __DHTMLEVENTS_H_
#define __DHTMLEVENTS_H_
#include "resource.h" // main symbols
#include <mshtmdid.h> // DHTML Behavior identifiers
#include <mshtmhst.h> // DHTML Behavior interfaces
#include <mshtml.h> // DHTML Object model
///////////////////////////////////////////////////////////////////////////
// CDHTMLEvents
class CBehavior;
class ATL_NO_VTABLE CDHTMLEvents :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CDHTMLEvents, &CLSID_DHTMLEvents>,
public IDispatchImpl<IDHTMLEvents, &IID_IDHTMLEvents, &LIBID_MYBEHLib>
{
public:
CDHTMLEvents()
{
m_pBehavior = NULL;
}
DECLARE_REGISTRY_RESOURCEID(IDR_DHTMLEVENTS)
DECLARE_NOT_AGGREGATABLE(CDHTMLEvents)
//DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CDHTMLEvents)
COM_INTERFACE_ENTRY2(HTMLElementEvents, IDHTMLEvents)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// IDispatchImpl override
STDMETHOD(Invoke)(DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pdispparams,
VARIANT* pvarResult,
EXCEPINFO* pexcepinfo,
UINT* puArgErr);
// Event Handlers (cfr. <PUBLIC:ATTACH>)
public:
void OnMouseOver();
void OnMouseOut();
// data members
CBehavior *m_pBehavior;
};
#endif //__DHTMLEVENTS_H_
Figure 10 DHTML Events // DHTMLEvents.cpp : Implementation of CDHTMLEvents
#include "stdafx.h"
#include "MyBeh.h"
#include "DHTMLEvents.h"
#include "Behavior.h"
/////////////////////////////////////////////////////////////////////////////
// CDHTMLEvents
HRESULT CDHTMLEvents::Invoke(DISPID dispidMember, REFIID riid, LCID lcid,
WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
EXCEPINFO* pexcepinfo, UINT* puArgErr)
{
switch (dispidMember)
{
case DISPID_HTMLELEMENTEVENTS_ONMOUSEOVER:
OnMouseOver();
break;
case DISPID_HTMLELEMENTEVENTS_ONMOUSEOUT:
OnMouseOut();
break;
default:
break;
}
return S_OK;
}
// OnMouseOver event handler
void CDHTMLEvents::OnMouseOver()
{
// highlight the text
if (m_pBehavior)
{
CComPtr<IHTMLStyle> spStyle;
m_pBehavior->m_spElem->get_style(&spStyle);
spStyle->put_color(CComVariant(L"red"));
}
}
// OnMouseOut event handler
void CDHTMLEvents::OnMouseOut()
{
// restore the text
if (m_pBehavior)
{
CComPtr<IHTMLStyle> spStyle;
m_pBehavior->m_spElem->get_style(&spStyle);
spStyle->put_color(m_pBehavior->m_oldColor);
}
}
Figure 15 Rendering Methods | Method | Description |
| Draw | Renders a behavior in the browser's client area. |
| GetPainterInfo | Provides MSHTML with the information it needs in order to issue proper calls to Draw. In particular, it relates the required z-order and whether DirectX is being used or not. |
| HitTestPoint | MSHTML calls this method when calls are made to elementFromPoint on the attached element. The implementation must check whether the point is within the behavior's area. |
| OnResize | Called by MSHTML to allow a behavior to resize when the element to which it is attached gets resized. |
Show: