IEMIMECTL.H
// IEMimeCtl.h : Declaration of the CIEMimeCtl 
 
#ifndef __IEMIMECTL_H_ 
#define __IEMIMECTL_H_ 
 
#include "resource.h"       // main symbols 
 
#include "CPIEMime.h" // Event interface Connection Point 
#include "BSCbck.h"   // Bind-status-callback download implementation 
// We're using VC5 COM support (_bstr_t and smart pointers) 
#include <comdef.h> 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CIEMimeCtl 
class ATL_NO_VTABLE CIEMimeCtl : 
public CComObjectRootEx<CComSingleThreadModel>, 
public CComCoClass<CIEMimeCtl,&CLSID_IEMimeCtl>, 
public CComControl<CIEMimeCtl>, 
public IDispatchImpl<IIEMimeCtl, &IID_IIEMimeCtl, &LIBID_IEMIMELib>, 
public IPersistStreamInitImpl<CIEMimeCtl>, 
public IOleControlImpl<CIEMimeCtl>, 
public IOleObjectImpl<CIEMimeCtl>, 
public IOleInPlaceActiveObjectImpl<CIEMimeCtl>, 
public IViewObjectExImpl<CIEMimeCtl>, 
public IConnectionPointContainerImpl<CIEMimeCtl>, 
public IOleInPlaceObjectWindowlessImpl<CIEMimeCtl>, 
public IPersistPropertyBagImpl<CIEMimeCtl>, 
public IPerPropertyBrowsingImpl<CIEMimeCtl>, 
public IObjectSafetyImpl<CIEMimeCtl>, 
public CProxyDIEMimeEvents<CIEMimeCtl>, 
public IPropertyNotifySinkCP<CIEMimeCtl, CComDynamicUnkArray>, 
public IProvideClassInfo2Impl<&CLSID_IEMimeCtl, &DIID__IEMimeEvents, &LIBID_IEMIMELib> 
{ 
public: 
CIEMimeCtl() 
{ 
m_nReadyState = READYSTATE_UNINITIALIZED; 
} 
 
DECLARE_REGISTRY_RESOURCEID(IDR_IEMIMECTL) 
 
BEGIN_COM_MAP(CIEMimeCtl)  
COM_INTERFACE_ENTRY(IDispatch) 
COM_INTERFACE_ENTRY(IIEMimeCtl) 
COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx) 
COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx) 
COM_INTERFACE_ENTRY_IMPL(IViewObjectEx) 
COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless) 
COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless) 
COM_INTERFACE_ENTRY_IMPL(IOleInPlaceObjectWindowless) 
COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject) 
COM_INTERFACE_ENTRY_IMPL(IOleControl) 
COM_INTERFACE_ENTRY_IMPL(IOleObject) 
COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit) 
COM_INTERFACE_ENTRY_IMPL_IID(IID_IPersist, IPersistPropertyBag) 
COM_INTERFACE_ENTRY_IMPL(IPersistPropertyBag) 
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer) 
COM_INTERFACE_ENTRY_IMPL(IObjectSafety) 
COM_INTERFACE_ENTRY(IProvideClassInfo2) 
COM_INTERFACE_ENTRY_IID(IID_IProvideClassInfo, IProvideClassInfo2) 
END_COM_MAP() 
 
BEGIN_PROPERTY_MAP(CIEMimeCtl) 
PROP_ENTRY("URL", 1, CLSID_NULL) 
PROP_ENTRY("Media", 2, CLSID_NULL) 
END_PROPERTY_MAP() 
 
BEGIN_CONNECTION_POINT_MAP(CIEMimeCtl) 
CONNECTION_POINT_ENTRY(DIID__IEMimeEvents) 
CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink) 
END_CONNECTION_POINT_MAP() 
 
BEGIN_MSG_MAP(CIEMimeCtl) 
MESSAGE_HANDLER(WM_PAINT, OnPaint) 
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) 
MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus) 
END_MSG_MAP() 
 
// IViewObjectEx 
STDMETHOD(GetViewStatus)(DWORD* pdwStatus) 
{ 
ATLTRACE(_T("IViewObjectExImpl::GetViewStatus\n")); 
*pdwStatus = VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE; 
return S_OK; 
} 
 
// IIEMimeCtl 
public: 
STDMETHOD(Reload)(); 
STDMETHOD(AboutBox)(); 
STDMETHOD(get_Cfformat)(/*[out, retval]*/ BSTR *pVal); 
//STDMETHOD(put_Cfformat)(/*[in]*/ BSTR newVal); // PUT not supported 
STDMETHOD(get_Media)(/*[out, retval]*/ BSTR *pVal); 
STDMETHOD(put_Media)(/*[in]*/ BSTR newVal); 
STDMETHOD(get_URL)(/*[out, retval]*/ BSTR *pVal); 
STDMETHOD(put_URL)(/*[in]*/ BSTR newVal);  
HRESULT OnDraw(ATL_DRAWINFO& di); 
 
// IOleControl override 
STDMETHOD(FreezeEvents)(BOOL bFreeze); 
 
// IPersistPropertybag override 
STDMETHOD(Load)(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog) 
{ 
ATLTRACE(_T("IPersistPropertyBagImpl::Load\n")); 
ATL_PROPMAP_ENTRY* pMap = GetPropertyMap(); 
_ASSERTE(pMap != NULL); 
m_nReadyState = READYSTATE_LOADING; // ADDED 
FireOnChanged(DISPID_READYSTATE); 
HRESULT hr = IPersistPropertyBag_Load(pPropBag, pErrorLog, pMap); 
m_nReadyState = READYSTATE_COMPLETE;// ADDED 
// Saying we're complete lets MSHTML proceed. See README.TXT for details. 
FireOnChanged(DISPID_READYSTATE); 
return hr; 
} 
 
void OnData(CBindStatusCallback2<CIEMimeCtl>* pbsc, BYTE* pBytes, DWORD dwSize, 
DWORD grfBSCF, FORMATETC *pformatetc, STGMEDIUM *pstgmed); 
 
HRESULT PreBindMoniker(CComPtr<IBindCtx> pBindCtx, CComPtr<IMoniker> pMoniker); 
 
void OnBindingFailure(HRESULT hr, LPCWSTR szError); 
 
// IObjectSafetyImpl doesn't support safe-for-persistence naturally. 
// See Microsoft Knowledge Base article Q168371 for more details on the following 
STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, 
DWORD *pdwSupportedOptions, 
DWORD *pdwEnabledOptions) 
{ 
   ATLTRACE(_T("CObjectSafetyImpl::GetInterfaceSafetyOptions\n")); 
   if (!pdwSupportedOptions || !pdwEnabledOptions) 
  return E_FAIL; 
   LPUNKNOWN pUnk; 
   if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) 
  // Our object doesn't even support this interface. 
  return E_NOINTERFACE; 
   else 
   { 
  // Cleanup after ourselves. 
  pUnk->Release(); 
  pUnk = NULL; 
   } 
   if (riid == IID_IDispatch)  
   { 
  *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; 
  *pdwEnabledOptions = m_dwSafety & 
   INTERFACESAFE_FOR_UNTRUSTED_CALLER; 
  return S_OK; 
// IEMime only supports persistence via IPersistPropertyBag 
   } 
   else if (riid == IID_IPersistPropertyBag)  
   { 
  *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA; 
  *pdwEnabledOptions = m_dwSafety & 
   INTERFACESAFE_FOR_UNTRUSTED_DATA; 
  return S_OK; 
   } 
   else 
   { 
  // No other interfaces in this control are 
  // safe for initializing or scripting. 
  *pdwSupportedOptions = 0; 
  *pdwEnabledOptions = 0; 
  return E_FAIL; 
   } 
} 
 
   STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, 
                                     DWORD dwOptionSetMask, 
                                     DWORD dwEnabledOptions) 
   { 
   ATLTRACE(_T("CObjectSafetyImpl::SetInterfaceSafetyOptions\n")); 
   if (!dwOptionSetMask && !dwEnabledOptions) return E_FAIL; 
   LPUNKNOWN pUnk; 
   if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) 
  // Our object doesn't even support this interface. 
  return E_NOINTERFACE; 
   else 
   { 
  // Cleanup after ourselves. 
  pUnk->Release(); 
  pUnk = NULL; 
   } 
   // Store our current safety level to return in 
   // GetInterfaceSafetyOptions 
   m_dwSafety |= dwEnabledOptions & dwOptionSetMask; 
   if ((riid == IID_IDispatch) && 
   (m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER)) 
  return S_OK; 
   else if ((riid == IID_IPersistPropertyBag) && 
 (m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_DATA)) 
  return S_OK; 
   else 
  return E_FAIL; 
   } 
 
// ReadyState property - not using CStockPropImpl because we only want this one stock-prop 
//                       and we only want it to be read-only 
long m_nReadyState; 
 
HRESULT STDMETHODCALLTYPE get_ReadyState(long* pnReadyState) 
{ 
ATLTRACE(_T("CIEMimeCTL - get_ReadyState - %d\n"),m_nReadyState); 
 
*pnReadyState = m_nReadyState; 
return S_OK; 
} 
 
public: 
_bstr_t m_bstrURL; 
_bstr_t m_bstrMedia; 
_bstr_t m_bstrCFFormat; 
 
}; 
 
#endif //__IEMIMECTL_H_