// This is a part of the Active Template Library. // Copyright (C) 1996-1997 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. #ifndef __ATLCTL_H__ #define __ATLCTL_H__ #ifndef __cplusplus #error ATL requires C++ compilation (use a .cpp suffix) #endif #include #include #include #pragma comment(lib, "gdi32.lib") #pragma comment(lib, "urlmon.lib") ATLAPI_(void) AtlHiMetricToPixel(const SIZEL * lpSizeInHiMetric, LPSIZEL lpSizeInPix); ATLAPI_(void) AtlPixelToHiMetric(const SIZEL * lpSizeInPix, LPSIZEL lpSizeInHiMetric); ATLAPI_(HDC) AtlCreateTargetDC(HDC hdc, DVTARGETDEVICE* ptd); // Include GUIDs for the new stock property dialogs contained in the dll MSStkProp.DLL #include "msstkppg.h" #define CLSID_MSStockFont CLSID_StockFontPage #define CLSID_MSStockColor CLSID_StockColorPage #define CLSID_MSStockPicture CLSID_StockPicturePage #ifndef ATL_NO_NAMESPACE namespace ATL { #endif #pragma pack(push, _ATL_PACKING) // Forward declarations // class ATL_NO_VTABLE CComControlBase; template class CComControl; class CComDispatchDriver; struct ATL_PROPMAP_ENTRY { LPCOLESTR szDesc; DISPID dispid; const CLSID* pclsidPropPage; const IID* piidDispatch; }; struct ATL_DRAWINFO { UINT cbSize; DWORD dwDrawAspect; LONG lindex; DVTARGETDEVICE* ptd; HDC hicTargetDev; HDC hdcDraw; LPCRECTL prcBounds; //Rectangle in which to draw LPCRECTL prcWBounds; //WindowOrg and Ext if metafile BOOL bOptimize; BOOL bZoomed; BOOL bRectInHimetric; SIZEL ZoomNum; //ZoomX = ZoomNum.cx/ZoomNum.cy SIZEL ZoomDen; }; ////////////////////////////////////////////////////////////////////////////// // CComDispatchDriver / Specialization of CComQIPtr class CComDispatchDriver { public: CComDispatchDriver() { p = NULL; } CComDispatchDriver(IDispatch* lp) { if ((p = lp) != NULL) p->AddRef(); } CComDispatchDriver(IUnknown* lp) { p=NULL; if (lp != NULL) lp->QueryInterface(IID_IDispatch, (void **)&p); } ~CComDispatchDriver() { if (p) p->Release(); } void Release() {if (p) p->Release(); p=NULL;} operator IDispatch*() {return p;} IDispatch& operator*() {_ASSERTE(p!=NULL); return *p; } IDispatch** operator&() {_ASSERTE(p==NULL); return &p; } IDispatch* operator->() {_ASSERTE(p!=NULL); return p; } IDispatch* operator=(IDispatch* lp){return (IDispatch*)AtlComPtrAssign((IUnknown**)&p, lp);} IDispatch* operator=(IUnknown* lp) { return (IDispatch*)AtlComQIPtrAssign((IUnknown**)&p, lp, IID_IDispatch); } BOOL operator!(){return (p == NULL) ? TRUE : FALSE;} HRESULT GetProperty(DISPID dwDispID, VARIANT* pVar) { _ASSERTE(p); return GetProperty(p, dwDispID, pVar); } HRESULT PutProperty(DISPID dwDispID, VARIANT* pVar) { _ASSERTE(p); return PutProperty(p, dwDispID, pVar); } static HRESULT GetProperty(IDispatch* pDisp, DISPID dwDispID, VARIANT* pVar); static HRESULT PutProperty(IDispatch* pDisp, DISPID dwDispID, VARIANT* pVar); IDispatch* p; }; ////////////////////////////////////////////////////////////////////////////// // CFirePropNotifyEvent class CFirePropNotifyEvent { public: static HRESULT FireOnRequestEdit(IUnknown* pUnk, DISPID dispID); static HRESULT FireOnChanged(IUnknown* pUnk, DISPID dispID); }; ////////////////////////////////////////////////////////////////////////////// // CFakeFirePropNotifyEvent class CFakeFirePropNotifyEvent { public: static HRESULT FireOnRequestEdit(IUnknown* /*pUnk*/, DISPID /*dispID*/) { return S_OK; } static HRESULT FireOnChanged(IUnknown* /*pUnk*/, DISPID /*dispID*/) { return S_OK; } }; typedef CFakeFirePropNotifyEvent _ATL_PROP_NOTIFY_EVENT_CLASS; ////////////////////////////////////////////////////////////////////////////// // CComControl class ATL_NO_VTABLE CComControlBase { public: CComControlBase(HWND& h) : m_hWndCD(h) { memset(this, 0, sizeof(CComControlBase)); m_phWndCD = &h; m_sizeExtent.cx = 2*2540; m_sizeExtent.cy = 2*2540; m_sizeNatural = m_sizeExtent; } ~CComControlBase() { if (m_hWndCD != NULL) ::DestroyWindow(m_hWndCD); ATLTRACE(_T("Control Destroyed\n")); } // methods public: // Control helper functions can go here // non-virtuals only please void SetDirty(BOOL bDirty) { m_bRequiresSave = bDirty; } BOOL GetDirty() { return m_bRequiresSave ? TRUE : FALSE; } void GetZoomInfo(ATL_DRAWINFO& di); HRESULT SendOnRename(IMoniker *pmk) { HRESULT hRes = S_OK; if (m_spOleAdviseHolder) hRes = m_spOleAdviseHolder->SendOnRename(pmk); return hRes; } HRESULT SendOnSave() { HRESULT hRes = S_OK; if (m_spOleAdviseHolder) hRes = m_spOleAdviseHolder->SendOnSave(); return hRes; } HRESULT SendOnClose() { HRESULT hRes = S_OK; if (m_spOleAdviseHolder) hRes = m_spOleAdviseHolder->SendOnClose(); return hRes; } HRESULT SendOnDataChange(DWORD advf = 0); HRESULT SendOnViewChange(DWORD dwAspect, LONG lindex = -1) { if (m_spAdviseSink) m_spAdviseSink->OnViewChange(dwAspect, lindex); return S_OK; } LRESULT OnSetFocus(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* bHandled */) { CComQIPtr spSite(m_spClientSite); if (m_bInPlaceActive && spSite) spSite->OnFocus(TRUE); return 0; } LRESULT OnKillFocus(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* bHandled */) { CComQIPtr spSite(m_spClientSite); if (m_bInPlaceActive && spSite) spSite->OnFocus(FALSE); return 0; } LRESULT OnGetDlgCode(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* bHandled */) { return 0; } HRESULT GetAmbientProperty(DISPID dispid, VARIANT& var) { HRESULT hRes = E_FAIL; if (m_spAmbientDispatch.p != NULL) hRes = m_spAmbientDispatch.GetProperty(dispid, &var); return hRes; } HRESULT GetAmbientAppearance(short& nAppearance) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_APPEARANCE, var); _ASSERTE(var.vt == VT_I2 || FAILED(hRes)); nAppearance = var.iVal; return hRes; } HRESULT GetAmbientBackColor(OLE_COLOR& BackColor) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_BACKCOLOR, var); _ASSERTE(var.vt == VT_I4 || FAILED(hRes)); BackColor = var.lVal; return hRes; } HRESULT GetAmbientDisplayName(BSTR& bstrDiaplayName) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_DISPLAYNAME, var); _ASSERTE(var.vt == VT_BSTR || FAILED(hRes)); bstrDiaplayName = var.bstrVal; return hRes; } HRESULT GetAmbientFont(IFont** ppFont) { // caller MUST Release the font! if (ppFont == NULL) return E_POINTER; CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FONT, var); _ASSERTE((var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH) || FAILED(hRes)); if (SUCCEEDED(hRes) && var.pdispVal) { if (var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH) hRes = var.pdispVal->QueryInterface(IID_IFont, (void**)ppFont); else hRes = DISP_E_BADVARTYPE; } return hRes; } HRESULT GetAmbientForeColor(OLE_COLOR& ForeColor) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FORECOLOR, var); _ASSERTE(var.vt == VT_I4 || FAILED(hRes)); ForeColor = var.lVal; return hRes; } HRESULT GetAmbientLocaleID(LCID& lcid) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_LOCALEID, var); _ASSERTE(var.vt == VT_I4 || FAILED(hRes)); lcid = var.lVal; return hRes; } HRESULT GetAmbientScaleUnits(BSTR& bstrScaleUnits) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SCALEUNITS, var); _ASSERTE(var.vt == VT_BSTR || FAILED(hRes)); bstrScaleUnits = var.bstrVal; return hRes; } HRESULT GetAmbientTextAlign(short& nTextAlign) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_TEXTALIGN, var); _ASSERTE(var.vt == VT_I2 || FAILED(hRes)); nTextAlign = var.iVal; return hRes; } HRESULT GetAmbientUserMode(BOOL& bUserMode) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_USERMODE, var); _ASSERTE(var.vt == VT_BOOL || FAILED(hRes)); bUserMode = var.boolVal; return hRes; } HRESULT GetAmbientUIDead(BOOL& bUIDead) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_UIDEAD, var); _ASSERTE(var.vt == VT_BOOL || FAILED(hRes)); bUIDead = var.boolVal; return hRes; } HRESULT GetAmbientShowGrabHandles(BOOL& bShowGrabHandles) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SHOWGRABHANDLES, var); _ASSERTE(var.vt == VT_BOOL || FAILED(hRes)); bShowGrabHandles = var.boolVal; return hRes; } HRESULT GetAmbientShowHatching(BOOL& bShowHatching) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SHOWHATCHING, var); _ASSERTE(var.vt == VT_BOOL || FAILED(hRes)); bShowHatching = var.boolVal; return hRes; } HRESULT GetAmbientMessageReflect(BOOL& bMessageReflect) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_MESSAGEREFLECT, var); _ASSERTE(var.vt == VT_BOOL || FAILED(hRes)); bMessageReflect = var.boolVal; return hRes; } HRESULT GetAmbientAutoClip(BOOL& bAutoClip) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_AUTOCLIP, var); _ASSERTE(var.vt == VT_BOOL || FAILED(hRes)); bAutoClip = var.boolVal; return hRes; } HRESULT GetAmbientDisplayAsDefault(BOOL& bDisplaysDefault) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_DISPLAYASDEFAULT, var); _ASSERTE(var.vt == VT_BOOL || FAILED(hRes)); bDisplaysDefault = var.boolVal; return hRes; } HRESULT GetAmbientSupportsMnemonics(BOOL& bSupportMnemonics) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SUPPORTSMNEMONICS, var); _ASSERTE(var.vt == VT_BOOL || FAILED(hRes)); bSupportMnemonics = var.boolVal; return hRes; } HRESULT GetAmbientPalette(HPALETTE& hPalette) { CComVariant var; HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_PALETTE, var); _ASSERTE(var.vt == VT_INT_PTR || FAILED(hRes)); hPalette = reinterpret_cast(var.byref); return hRes; } BOOL DoesVerbUIActivate(LONG iVerb) { BOOL b = FALSE; switch (iVerb) { case OLEIVERB_UIACTIVATE: case OLEIVERB_PRIMARY: b = TRUE; break; } // if no ambient dispatch then in old style OLE container if (DoesVerbActivate(iVerb) && m_spAmbientDispatch.p == NULL) b = TRUE; return b; } BOOL DoesVerbActivate(LONG iVerb) { BOOL b = FALSE; switch (iVerb) { case OLEIVERB_UIACTIVATE: case OLEIVERB_PRIMARY: case OLEIVERB_SHOW: case OLEIVERB_INPLACEACTIVATE: b = TRUE; break; } return b; } BOOL SetControlFocus(BOOL bGrab); HRESULT IQuickActivate_QuickActivate(QACONTAINER *pQACont, QACONTROL *pQACtrl); HRESULT IPersistPropertyBag_Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog, ATL_PROPMAP_ENTRY* pMap); HRESULT IPersistPropertyBag_Save(LPPROPERTYBAG pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties, ATL_PROPMAP_ENTRY* pMap); HRESULT ISpecifyPropertyPages_GetPages(CAUUID* pPages, ATL_PROPMAP_ENTRY* pMap); HRESULT DoVerbProperties(LPCRECT /* prcPosRect */, HWND hwndParent); HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect = NULL); HRESULT IPersistStreamInit_Load(LPSTREAM pStm, ATL_PROPMAP_ENTRY* pMap); HRESULT IPersistStreamInit_Save(LPSTREAM pStm, BOOL /* fClearDirty */, ATL_PROPMAP_ENTRY* pMap); HRESULT IOleObject_SetClientSite(IOleClientSite *pClientSite); HRESULT IOleObject_GetClientSite(IOleClientSite **ppClientSite); HRESULT IOleObject_Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection); HRESULT IOleObject_Close(DWORD dwSaveOption); HRESULT IOleObject_SetExtent(DWORD dwDrawAspect, SIZEL *psizel); HRESULT IOleInPlaceObject_InPlaceDeactivate(void); HRESULT IOleInPlaceObject_UIDeactivate(void); HRESULT IOleInPlaceObject_SetObjectRects(LPCRECT prcPos,LPCRECT prcClip); HRESULT IViewObject_Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw, LPCRECTL prcBounds, LPCRECTL prcWBounds); HRESULT IDataObject_GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium); HRESULT FireViewChange(); LRESULT OnPaint(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* lResult */); virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos) = 0; virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv) = 0; virtual HRESULT OnDrawAdvanced(ATL_DRAWINFO& di); virtual HRESULT OnDraw(ATL_DRAWINFO& di) { return S_OK; } // Attributes public: CComPtr m_spInPlaceSite; CComPtr m_spDataAdviseHolder; CComPtr m_spOleAdviseHolder; CComPtr m_spClientSite; CComPtr m_spAdviseSink; CComDispatchDriver m_spAmbientDispatch; SIZE m_sizeNatural; //unscaled size in himetric SIZE m_sizeExtent; //current extents in himetric RECT m_rcPos; // position in pixels union { HWND& m_hWndCD; HWND* m_phWndCD; }; union { // m_nFreezeEvents is the only one actually used int m_nFreezeEvents; // count of freezes versus thaws // These are here to make stock properties work IPictureDisp* m_pMouseIcon; IPictureDisp* m_pPicture; IFontDisp* m_pFont; OLE_COLOR m_clrBackColor; OLE_COLOR m_clrBorderColor; OLE_COLOR m_clrFillColor; OLE_COLOR m_clrForeColor; BSTR m_bstrText; BSTR m_bstrCaption; BOOL m_bValid; BOOL m_bTabStop; BOOL m_bBorderVisible; BOOL m_bEnabled; long m_nBackStyle; long m_nBorderStyle; long m_nBorderWidth; long m_nDrawMode; long m_nDrawStyle; long m_nDrawWidth; long m_nFillStyle; long m_nAppearance; long m_nMousePointer; long m_nReadyState; }; unsigned m_bNegotiatedWnd:1; unsigned m_bWndLess:1; unsigned m_bInPlaceActive:1; unsigned m_bUIActive:1; unsigned m_bUsingWindowRgn:1; unsigned m_bInPlaceSiteEx:1; unsigned m_bWindowOnly:1; unsigned m_bRequiresSave:1; unsigned m_bWasOnceWindowless:1; unsigned m_bAutoSize:1; //SetExtent fails if size doesn't match existing unsigned m_bRecomposeOnResize:1; //implies OLEMISC_RECOMPOSEONRESIZE unsigned m_bResizeNatural:1; //resize natural extent on SetExtent unsigned m_bDrawFromNatural:1; //instead of m_sizeExtent unsigned m_bDrawGetDataInHimetric:1; //instead of pixels }; template class ATL_NO_VTABLE CComControl : public CComControlBase, public CWindowImpl { public: CComControl() : CComControlBase(m_hWnd) {} HRESULT FireOnRequestEdit(DISPID dispID) { T* pT = static_cast(this); return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnRequestEdit(pT->GetUnknown(), dispID); } HRESULT FireOnChanged(DISPID dispID) { T* pT = static_cast(this); return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnChanged(pT->GetUnknown(), dispID); } virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv) { T* pT = static_cast(this); return pT->_InternalQueryInterface(iid, ppv); } virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos) { T* pT = static_cast(this); return pT->Create(hWndParent, rcPos); } }; // Forward declarations // template class IPersistImpl; template class IPersistStreamInitImpl; template class IPersistStorageImpl; template class IPersistPropertyBagImpl; template class IOleControlImpl; template class IRunnableObjectImpl; template class IQuickActivateImpl; template class IOleObjectImpl; template class IPropertyPageImpl; template class IPropertyPage2Impl; template class IPerPropertyBrowsingImpl; template class IViewObjectExImpl; template class IOleWindowImpl; template class ISpecifyPropertyPagesImpl; template class IPointerInactiveImpl; template class IPropertyNotifySinkCP; template class IBindStatusCallbackImpl; template class CBindStatusCallback; ////////////////////////////////////////////////////////////////////////////// // IPersistImpl template class ATL_NO_VTABLE IPersistImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistImpl) // IPersist STDMETHOD(GetClassID)(CLSID *pClassID) { ATLTRACE(_T("IPersistImpl::GetClassID\n")); T* pT = static_cast(this); *pClassID = pT->GetObjectCLSID(); return S_OK; } }; #define BEGIN_PROPERTY_MAP(theClass) \ typedef _ATL_PROP_NOTIFY_EVENT_CLASS __ATL_PROP_NOTIFY_EVENT_CLASS; \ static ATL_PROPMAP_ENTRY* GetPropertyMap()\ {\ static ATL_PROPMAP_ENTRY pPropMap[] = \ { #define PROP_ENTRY(szDesc, dispid, clsid) \ {OLESTR(szDesc), dispid, &clsid, &IID_IDispatch}, #define PROP_ENTRY_EX(szDesc, dispid, clsid, iidDispatch) \ {OLESTR(szDesc), dispid, &clsid, &iidDispatch}, #define PROP_PAGE(clsid) \ {NULL, NULL, &clsid, &IID_NULL}, #define END_PROPERTY_MAP() \ {NULL, 0, NULL, &IID_NULL} \ }; \ return pPropMap; \ } ////////////////////////////////////////////////////////////////////////////// // IPersistStreamInitImpl template class ATL_NO_VTABLE IPersistStreamInitImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistStreamInitImpl) // IPersist STDMETHOD(GetClassID)(CLSID *pClassID) { ATLTRACE(_T("IPersistStreamInitImpl::GetClassID\n")); T* pT = static_cast(this); *pClassID = pT->GetObjectCLSID(); return S_OK; } // IPersistStream STDMETHOD(IsDirty)() { ATLTRACE(_T("IPersistStreamInitImpl::IsDirty\n")); T* pT = static_cast(this); return (pT->m_bRequiresSave) ? S_OK : S_FALSE; } STDMETHOD(Load)(LPSTREAM pStm) { ATLTRACE(_T("IPersistStreamInitImpl::Load\n")); T* pT = static_cast(this); return pT->IPersistStreamInit_Load(pStm, T::GetPropertyMap()); } STDMETHOD(Save)(LPSTREAM pStm, BOOL fClearDirty) { T* pT = static_cast(this); ATLTRACE(_T("IPersistStreamInitImpl::Save\n")); return pT->IPersistStreamInit_Save(pStm, fClearDirty, T::GetPropertyMap()); } STDMETHOD(GetSizeMax)(ULARGE_INTEGER FAR* /* pcbSize */) { ATLTRACENOTIMPL(_T("IPersistStreamInitImpl::GetSizeMax")); } // IPersistStreamInit STDMETHOD(InitNew)() { T* pT = static_cast(this); ATLTRACE(_T("IPersistStreamInitImpl::InitNew\n")); pT->SendOnDataChange(); return S_OK; } }; ////////////////////////////////////////////////////////////////////////////// // IPersistStorageImpl template class ATL_NO_VTABLE IPersistStorageImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistStorageImpl) // IPersist STDMETHOD(GetClassID)(CLSID *pClassID) { ATLTRACE(_T("IPersistStorageImpl::GetClassID\n")); T* pT = static_cast(this); *pClassID = pT->GetObjectCLSID(); return S_OK; } // IPersistStorage STDMETHOD(IsDirty)(void) { ATLTRACE(_T("IPersistStorageImpl::IsDirty\n")); T* pT = static_cast(this); CComPtr p; p.p = IPSI_GetIPersistStreamInit(); return (p != NULL) ? p->IsDirty() : E_FAIL; } STDMETHOD(InitNew)(IStorage*) { ATLTRACE(_T("IPersistStorageImpl::InitNew\n")); T* pT = static_cast(this); CComPtr p; p.p = IPSI_GetIPersistStreamInit(); return (p != NULL) ? p->InitNew() : E_FAIL; } STDMETHOD(Load)(IStorage* pStorage) { ATLTRACE(_T("IPersistStorageImpl::Load\n")); T* pT = static_cast(this); CComPtr p; p.p = IPSI_GetIPersistStreamInit(); HRESULT hr = E_FAIL; if (p != NULL) { CComPtr spStream; hr = pStorage->OpenStream(OLESTR("Contents"), NULL, STGM_DIRECT | STGM_SHARE_EXCLUSIVE, 0, &spStream); if (SUCCEEDED(hr)) hr = p->Load(spStream); } return hr; } STDMETHOD(Save)(IStorage* pStorage, BOOL fSameAsLoad) { ATLTRACE(_T("IPersistStorageImpl::Save\n")); T* pT = static_cast(this); CComPtr p; p.p = IPSI_GetIPersistStreamInit(); HRESULT hr = E_FAIL; if (p != NULL) { CComPtr spStream; static LPCOLESTR vszContents = OLESTR("Contents"); hr = pStorage->CreateStream(vszContents, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &spStream); if (SUCCEEDED(hr)) hr = p->Save(spStream, fSameAsLoad); } return hr; } STDMETHOD(SaveCompleted)(IStorage* /* pStorage */) { ATLTRACE(_T("IPersistStorageImpl::SaveCompleted\n")); return S_OK; } STDMETHOD(HandsOffStorage)(void) { ATLTRACE(_T("IPersistStorageImpl::HandsOffStorage\n")); return S_OK; } private: IPersistStreamInit* IPSI_GetIPersistStreamInit(); }; template IPersistStreamInit* IPersistStorageImpl::IPSI_GetIPersistStreamInit() { T* pT = static_cast(this); IPersistStreamInit* p; if (FAILED(pT->GetUnknown()->QueryInterface(IID_IPersistStreamInit, (void**)&p))) pT->_InternalQueryInterface(IID_IPersistStreamInit, (void**)&p); return p; } ////////////////////////////////////////////////////////////////////////////// // IPersistPropertyBagImpl template class ATL_NO_VTABLE IPersistPropertyBagImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistPropertyBagImpl) // IPersist STDMETHOD(GetClassID)(CLSID *pClassID) { ATLTRACE(_T("IPersistPropertyBagImpl::GetClassID\n")); T* pT = static_cast(this); *pClassID = pT->GetObjectCLSID(); return S_OK; } // IPersistPropertyBag // STDMETHOD(InitNew)() { ATLTRACE(_T("IPersistPropertyBagImpl::InitNew\n")); return S_OK; } STDMETHOD(Load)(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog) { ATLTRACE(_T("IPersistPropertyBagImpl::Load\n")); T* pT = static_cast(this); ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap(); _ASSERTE(pMap != NULL); return pT->IPersistPropertyBag_Load(pPropBag, pErrorLog, pMap); } STDMETHOD(Save)(LPPROPERTYBAG pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties) { ATLTRACE(_T("IPersistPropertyBagImpl::Save\n")); T* pT = static_cast(this); ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap(); _ASSERTE(pMap != NULL); return pT->IPersistPropertyBag_Save(pPropBag, fClearDirty, fSaveAllProperties, pMap); } }; ////////////////////////////////////////////////////////////////////////////// // IOleControlImpl template class ATL_NO_VTABLE IOleControlImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleControlImpl) // IOleControl methods // STDMETHOD(GetControlInfo)(LPCONTROLINFO /* pCI */) { ATLTRACENOTIMPL(_T("IOleControlImpl::GetControlInfo")); } STDMETHOD(OnMnemonic)(LPMSG /* pMsg */) { ATLTRACENOTIMPL(_T("IOleControlImpl::OnMnemonic")); } STDMETHOD(OnAmbientPropertyChange)(DISPID dispid) { dispid; ATLTRACE(_T("IOleControlImpl::OnAmbientPropertyChange\n")); ATLTRACE(_T(" -- DISPID = %d (%d)\n"), dispid); return S_OK; } STDMETHOD(FreezeEvents)(BOOL bFreeze) { T* pT = static_cast(this); ATLTRACE(_T("IOleControlImpl::FreezeEvents\n")); if (bFreeze) pT->m_nFreezeEvents++; else pT->m_nFreezeEvents--; return S_OK; } }; ////////////////////////////////////////////////////////////////////////////// // IQuickActivateImpl template class ATL_NO_VTABLE IQuickActivateImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IQuickActivateImpl) // IQuickActivate // STDMETHOD(QuickActivate)(QACONTAINER *pQACont, QACONTROL *pQACtrl) { T* pT = static_cast(this); ATLTRACE(_T("IQuickActivateImpl::QuickActivate\n")); return pT->IQuickActivate_QuickActivate(pQACont, pQACtrl); } STDMETHOD(SetContentExtent)(LPSIZEL pSize) { T* pT = static_cast(this); ATLTRACE(_T("IQuickActivateImpl::SetContentExtent\n")); return pT->IOleObjectImpl::SetExtent(DVASPECT_CONTENT, pSize); } STDMETHOD(GetContentExtent)(LPSIZEL pSize) { T* pT = static_cast(this); ATLTRACE(_T("IQuickActivateImpl::GetContentExtent\n")); return pT->IOleObjectImpl::GetExtent(DVASPECT_CONTENT, pSize); } }; ////////////////////////////////////////////////////////////////////////////// // IOleObjectImpl template class ATL_NO_VTABLE IOleObjectImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleObjectImpl) // IOleObject // STDMETHOD(SetClientSite)(IOleClientSite *pClientSite) { T* pT = static_cast(this); ATLTRACE(_T("IOleObjectImpl::SetClientSite\n")); return pT->IOleObject_SetClientSite(pClientSite); } STDMETHOD(GetClientSite)(IOleClientSite **ppClientSite) { T* pT = static_cast(this); ATLTRACE(_T("IOleObjectImpl::GetClientSite\n")); return pT->IOleObject_GetClientSite(ppClientSite); } STDMETHOD(SetHostNames)(LPCOLESTR /* szContainerApp */, LPCOLESTR /* szContainerObj */) { ATLTRACE(_T("IOleObjectImpl::SetHostNames\n")); return S_OK; } STDMETHOD(Close)(DWORD dwSaveOption) { T* pT = static_cast(this); ATLTRACE(_T("IOleObjectImpl::Close\n")); return pT->IOleObject_Close(dwSaveOption); } STDMETHOD(SetMoniker)(DWORD /* dwWhichMoniker */, IMoniker* /* pmk */) { ATLTRACENOTIMPL(_T("IOleObjectImpl::SetMoniker")); } STDMETHOD(GetMoniker)(DWORD /* dwAssign */, DWORD /* dwWhichMoniker */, IMoniker** /* ppmk */) { ATLTRACENOTIMPL(_T("IOleObjectImpl::GetMoniker")); } STDMETHOD(InitFromData)(IDataObject* /* pDataObject */, BOOL /* fCreation */, DWORD /* dwReserved */) { ATLTRACENOTIMPL(_T("IOleObjectImpl::InitFromData")); } STDMETHOD(GetClipboardData)(DWORD /* dwReserved */, IDataObject** /* ppDataObject */) { ATLTRACENOTIMPL(_T("IOleObjectImpl::GetClipboardData")); } // Helpers for DoVerb - Over-rideable in user class HRESULT DoVerbPrimary(LPCRECT prcPosRect, HWND hwndParent) { T* pT = static_cast(this); BOOL bDesignMode = FALSE; CComVariant var; // if container doesn't support this property // don't allow design mode HRESULT hRes = pT->GetAmbientProperty(DISPID_AMBIENT_USERMODE, var); if (SUCCEEDED(hRes) && var.vt == VT_BOOL && !var.boolVal) bDesignMode = TRUE; if (bDesignMode) return pT->DoVerbProperties(prcPosRect, hwndParent); else return pT->DoVerbInPlaceActivate(prcPosRect, hwndParent); } HRESULT DoVerbShow(LPCRECT prcPosRect, HWND /* hwndParent */) { T* pT = static_cast(this); return pT->InPlaceActivate(OLEIVERB_SHOW, prcPosRect); } HRESULT DoVerbInPlaceActivate(LPCRECT prcPosRect, HWND /* hwndParent */) { T* pT = static_cast(this); return pT->InPlaceActivate(OLEIVERB_INPLACEACTIVATE, prcPosRect); } HRESULT DoVerbUIActivate(LPCRECT prcPosRect, HWND /* hwndParent */) { T* pT = static_cast(this); return pT->InPlaceActivate(OLEIVERB_UIACTIVATE, prcPosRect); } HRESULT DoVerbHide(LPCRECT /* prcPosRect */, HWND /* hwndParent */) { T* pT = static_cast(this); pT->UIDeactivate(); if (pT->m_hWnd) pT->ShowWindow(SW_HIDE); return S_OK; } HRESULT DoVerbOpen(LPCRECT /* prcPosRect */, HWND /* hwndParent */) { return S_OK; } HRESULT DoVerbDiscardUndo(LPCRECT /* prcPosRect */, HWND /* hwndParent */) { return S_OK; } STDMETHOD(DoVerb)(LONG iVerb, LPMSG /* lpmsg */, IOleClientSite* /* pActiveSite */, LONG /* lindex */, HWND hwndParent, LPCRECT lprcPosRect) { T* pT = static_cast(this); ATLTRACE(_T("IOleObjectImpl::DoVerb\n")); _ASSERTE(pT->m_spClientSite); HRESULT hr = E_NOTIMPL; switch (iVerb) { case OLEIVERB_PRIMARY: hr = pT->DoVerbPrimary(lprcPosRect, hwndParent); break; case OLEIVERB_SHOW: hr = pT->DoVerbShow(lprcPosRect, hwndParent); break; case OLEIVERB_INPLACEACTIVATE: hr = pT->DoVerbInPlaceActivate(lprcPosRect, hwndParent); break; case OLEIVERB_UIACTIVATE: hr = pT->DoVerbUIActivate(lprcPosRect, hwndParent); break; case OLEIVERB_HIDE: hr = pT->DoVerbHide(lprcPosRect, hwndParent); break; case OLEIVERB_OPEN: hr = pT->DoVerbOpen(lprcPosRect, hwndParent); break; case OLEIVERB_DISCARDUNDOSTATE: hr = pT->DoVerbDiscardUndo(lprcPosRect, hwndParent); break; case OLEIVERB_PROPERTIES: hr = pT->DoVerbProperties(lprcPosRect, hwndParent); } return hr; } STDMETHOD(EnumVerbs)(IEnumOLEVERB **ppEnumOleVerb) { ATLTRACE(_T("IOleObjectImpl::EnumVerbs\n")); _ASSERTE(ppEnumOleVerb); if (!ppEnumOleVerb) return E_POINTER; return OleRegEnumVerbs(T::GetObjectCLSID(), ppEnumOleVerb); } STDMETHOD(Update)(void) { ATLTRACE(_T("IOleObjectImpl::Update\n")); return S_OK; } STDMETHOD(IsUpToDate)(void) { ATLTRACE(_T("IOleObjectImpl::IsUpToDate\n")); return S_OK; } STDMETHOD(GetUserClassID)(CLSID *pClsid) { ATLTRACE(_T("IOleObjectImpl::GetUserClassID\n")); _ASSERTE(pClsid); if (!pClsid) return E_POINTER; *pClsid = T::GetObjectCLSID(); return S_OK; } STDMETHOD(GetUserType)(DWORD dwFormOfType, LPOLESTR *pszUserType) { ATLTRACE(_T("IOleObjectImpl::GetUserType\n")); return OleRegGetUserType(T::GetObjectCLSID(), dwFormOfType, pszUserType); } STDMETHOD(SetExtent)(DWORD dwDrawAspect, SIZEL *psizel) { T* pT = static_cast(this); ATLTRACE(_T("IOleObjectImpl::SetExtent\n")); return pT->IOleObject_SetExtent(dwDrawAspect, psizel); } STDMETHOD(GetExtent)(DWORD dwDrawAspect, SIZEL *psizel) { T* pT = static_cast(this); ATLTRACE(_T("IOleObjectImpl::GetExtent\n")); if (dwDrawAspect != DVASPECT_CONTENT) return E_FAIL; if (psizel == NULL) return E_POINTER; *psizel = pT->m_sizeExtent; return S_OK; } STDMETHOD(Advise)(IAdviseSink *pAdvSink, DWORD *pdwConnection) { T* pT = static_cast(this); ATLTRACE(_T("IOleObjectImpl::Advise\n")); return pT->IOleObject_Advise(pAdvSink, pdwConnection); } STDMETHOD(Unadvise)(DWORD dwConnection) { T* pT = static_cast(this); ATLTRACE(_T("IOleObjectImpl::Unadvise\n")); HRESULT hRes = E_FAIL; if (pT->m_spOleAdviseHolder != NULL) hRes = pT->m_spOleAdviseHolder->Unadvise(dwConnection); return hRes; } STDMETHOD(EnumAdvise)(IEnumSTATDATA **ppenumAdvise) { T* pT = static_cast(this); ATLTRACE(_T("IOleObjectImpl::EnumAdvise\n")); HRESULT hRes = E_FAIL; if (pT->m_spOleAdviseHolder != NULL) hRes = pT->m_spOleAdviseHolder->EnumAdvise(ppenumAdvise); return hRes; } STDMETHOD(GetMiscStatus)(DWORD dwAspect, DWORD *pdwStatus) { ATLTRACE(_T("IOleObjectImpl::GetMiscStatus\n")); return OleRegGetMiscStatus(T::GetObjectCLSID(), dwAspect, pdwStatus); } STDMETHOD(SetColorScheme)(LOGPALETTE* /* pLogpal */) { ATLTRACENOTIMPL(_T("IOleObjectImpl::SetColorScheme")); } }; //local struct used for implementation #pragma pack(push, 1) struct _ATL_DLGTEMPLATEEX { WORD dlgVer; WORD signature; DWORD helpID; DWORD exStyle; DWORD style; WORD cDlgItems; short x; short y; short cx; short cy; }; #pragma pack(pop) ////////////////////////////////////////////////////////////////////////////// // IPropertyPageImpl template class ATL_NO_VTABLE IPropertyPageImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleControlImpl) void SetDirty(BOOL bDirty) { T* pT = static_cast(this); if (!pT->m_bDirty && bDirty) pT->m_pPageSite->OnStatusChange(PROPPAGESTATUS_DIRTY | PROPPAGESTATUS_VALIDATE); pT->m_bDirty = bDirty; } IPropertyPageImpl() { T* pT = static_cast(this); pT->m_pPageSite = NULL; pT->m_size.cx = 0; pT->m_size.cy = 0; pT->m_dwTitleID = 0; pT->m_dwHelpFileID = 0; pT->m_dwDocStringID = 0; pT->m_dwHelpContext = 0; pT->m_ppUnk = NULL; pT->m_nObjects = 0; pT->m_bDirty = FALSE; pT->m_hWnd = NULL; } ~IPropertyPageImpl() { T* pT = static_cast(this); if (pT->m_pPageSite != NULL) pT->m_pPageSite->Release(); for (UINT i = 0; i < m_nObjects; i++) pT->m_ppUnk[i]->Release(); delete[] pT->m_ppUnk; } // IPropertyPage // STDMETHOD(SetPageSite)(IPropertyPageSite *pPageSite) { T* pT = static_cast(this); ATLTRACE(_T("IPropertyPageImpl::SetPageSite\n")); if (!pPageSite && pT->m_pPageSite) { pT->m_pPageSite->Release(); return S_OK; } if (!pPageSite && !pT->m_pPageSite) return S_OK; if (pPageSite && pT->m_pPageSite) { ATLTRACE(_T("Error : setting page site again with non NULL value\n")); return E_UNEXPECTED; } pT->m_pPageSite = pPageSite; pT->m_pPageSite->AddRef(); return S_OK; } STDMETHOD(Activate)(HWND hWndParent, LPCRECT pRect, BOOL /* bModal */) { T* pT = static_cast(this); ATLTRACE(_T("IPropertyPageImpl::Activate\n")); if (pRect == NULL) { ATLTRACE(_T("Error : Passed a NULL rect\n")); return E_POINTER; } pT->m_hWnd = pT->Create(hWndParent); Move(pRect); m_size.cx = pRect->right - pRect->left; m_size.cy = pRect->bottom - pRect->top; return S_OK; } STDMETHOD(Deactivate)( void) { T* pT = static_cast(this); ATLTRACE(_T("IPropertyPageImpl::Deactivate\n")); if (pT->m_hWnd) { ATLTRACE(_T("Destroying Dialog\n")); if (::IsWindow(pT->m_hWnd)) pT->DestroyWindow(); pT->m_hWnd = NULL; } return S_OK; } STDMETHOD(GetPageInfo)(PROPPAGEINFO *pPageInfo) { T* pT = static_cast(this); ATLTRACE(_T("IPropertyPageImpl::GetPageInfo\n")); if (pPageInfo == NULL) { ATLTRACE(_T("Error : PROPPAGEINFO passed == NULL\n")); return E_POINTER; } HRSRC hRsrc = FindResource(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD), RT_DIALOG); if (hRsrc == NULL) { ATLTRACE(_T("Could not find resource template\n")); return E_UNEXPECTED; } HGLOBAL hGlob = LoadResource(_Module.GetResourceInstance(), hRsrc); DLGTEMPLATE* pTemp = (DLGTEMPLATE*)LockResource(hGlob); if (pTemp == NULL) { ATLTRACE(_T("Could not load resource template\n")); return E_UNEXPECTED; } pT->GetDialogSize(pTemp, &m_size); pPageInfo->cb = sizeof(PROPPAGEINFO); pPageInfo->pszTitle = LoadStringHelper(pT->m_dwTitleID); pPageInfo->size = m_size; pPageInfo->pszHelpFile = LoadStringHelper(pT->m_dwHelpFileID); pPageInfo->pszDocString = LoadStringHelper(pT->m_dwDocStringID); pPageInfo->dwHelpContext = pT->m_dwHelpContext; return S_OK; } STDMETHOD(SetObjects)(ULONG nObjects, IUnknown **ppUnk) { T* pT = static_cast(this); ATLTRACE(_T("IPropertyPageImpl::SetObjects\n")); if (ppUnk == NULL) return E_POINTER; if (pT->m_ppUnk != NULL && pT->m_nObjects > 0) { for (UINT iObj = 0; iObj < pT->m_nObjects; iObj++) pT->m_ppUnk[iObj]->Release(); delete [] pT->m_ppUnk; } pT->m_ppUnk = NULL; ATLTRY(pT->m_ppUnk = new IUnknown*[nObjects]); if (pT->m_ppUnk == NULL) return E_OUTOFMEMORY; for (UINT i = 0; i < nObjects; i++) { ppUnk[i]->AddRef(); pT->m_ppUnk[i] = ppUnk[i]; } pT->m_nObjects = nObjects; return S_OK; } STDMETHOD(Show)(UINT nCmdShow) { T* pT = static_cast(this); ATLTRACE(_T("IPropertyPageImpl::Show\n")); if (pT->m_hWnd == NULL) return E_UNEXPECTED; ShowWindow(pT->m_hWnd, nCmdShow); return S_OK; } STDMETHOD(Move)(LPCRECT pRect) { T* pT = static_cast(this); ATLTRACE(_T("IPropertyPageImpl::Move\n")); if (pT->m_hWnd == NULL) return E_UNEXPECTED; if (pRect == NULL) return E_POINTER; MoveWindow(pT->m_hWnd, pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top, TRUE); return S_OK; } STDMETHOD(IsPageDirty)(void) { T* pT = static_cast(this); ATLTRACE(_T("IPropertyPageImpl::IsPageDirty\n")); return pT->m_bDirty ? S_OK : S_FALSE; } STDMETHOD(Apply)(void) { T* pT = static_cast(this); ATLTRACE(_T("IPropertyPageImpl::Apply\n")); return S_OK; } STDMETHOD(Help)(LPCOLESTR pszHelpDir) { T* pT = static_cast(this); USES_CONVERSION; ATLTRACE(_T("IPropertyPageImpl::Help\n")); WinHelp(pT->m_hWnd, OLE2CT(pszHelpDir), HELP_CONTEXTPOPUP, NULL); return S_OK; } STDMETHOD(TranslateAccelerator)(MSG *pMsg) { T* pT = static_cast(this); ATLTRACE(_T("IPropertyPageImpl::TranslateAccelerator\n")); if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) && (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST)) return S_FALSE; return (IsDialogMessage(pT->m_hWnd, pMsg)) ? S_OK : S_FALSE; } IPropertyPageSite* m_pPageSite; IUnknown** m_ppUnk; ULONG m_nObjects; SIZE m_size; UINT m_dwTitleID; UINT m_dwHelpFileID; UINT m_dwDocStringID; DWORD m_dwHelpContext; BOOL m_bDirty; //methods public: BEGIN_MSG_MAP(IPropertyPageImpl) MESSAGE_HANDLER(WM_STYLECHANGING, OnStyleChange) END_MSG_MAP() LRESULT OnStyleChange(UINT, WPARAM wParam, LPARAM lParam, BOOL&) { if (wParam == GWL_EXSTYLE) { LPSTYLESTRUCT lpss = (LPSTYLESTRUCT) lParam; lpss->styleNew |= WS_EX_CONTROLPARENT; return 0; } return 1; } LPOLESTR LoadStringHelper(UINT idRes) { USES_CONVERSION; TCHAR szTemp[_MAX_PATH]; LPOLESTR sz = (LPOLESTR)CoTaskMemAlloc(_MAX_PATH*sizeof(OLECHAR)); if (sz == NULL) return NULL; sz[0] = NULL; if (LoadString(_Module.GetResourceInstance(), idRes, szTemp, _MAX_PATH)) ocscpy(sz, T2OLE(szTemp)); else { ATLTRACE(_T("Error : Failed to load string from res\n")); } return sz; } void GetDialogSize(const DLGTEMPLATE* pTemplate, SIZE* pSize) { // If the dialog has a font we use it otherwise we default // to the system font. if (HasFont(pTemplate)) { TCHAR szFace[LF_FACESIZE]; WORD wFontSize = 0; GetFont(pTemplate, szFace, &wFontSize); GetSizeInDialogUnits(pTemplate, pSize); ConvertDialogUnitsToPixels(szFace, wFontSize, pSize); } else { GetSizeInDialogUnits(pTemplate, pSize); LONG nDlgBaseUnits = GetDialogBaseUnits(); pSize->cx = MulDiv(pSize->cx, LOWORD(nDlgBaseUnits), 4); pSize->cy = MulDiv(pSize->cy, HIWORD(nDlgBaseUnits), 8); } } static void ConvertDialogUnitsToPixels(LPCTSTR pszFontFace, WORD wFontSize, SIZE* pSizePixel) { // Attempt to create the font to be used in the dialog box UINT cxSysChar, cySysChar; LOGFONT lf; HDC hDC = ::GetDC(NULL); int cxDlg = pSizePixel->cx; int cyDlg = pSizePixel->cy; ZeroMemory(&lf, sizeof(LOGFONT)); lf.lfHeight = -MulDiv(wFontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72); lf.lfWeight = FW_NORMAL; lf.lfCharSet = DEFAULT_CHARSET; lstrcpy(lf.lfFaceName, pszFontFace); HFONT hNewFont = CreateFontIndirect(&lf); if (hNewFont != NULL) { TEXTMETRIC tm; SIZE size; HFONT hFontOld = (HFONT)SelectObject(hDC, hNewFont); GetTextMetrics(hDC, &tm); cySysChar = tm.tmHeight + tm.tmExternalLeading; ::GetTextExtentPoint(hDC, _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52, &size); cxSysChar = (size.cx + 26) / 52; SelectObject(hDC, hFontOld); DeleteObject(hNewFont); } else { // Could not create the font so just use the system's values cxSysChar = LOWORD(GetDialogBaseUnits()); cySysChar = HIWORD(GetDialogBaseUnits()); } ::ReleaseDC(NULL, hDC); // Translate dialog units to pixels pSizePixel->cx = MulDiv(cxDlg, cxSysChar, 4); pSizePixel->cy = MulDiv(cyDlg, cySysChar, 8); } static BOOL IsDialogEx(const DLGTEMPLATE* pTemplate) { return ((_ATL_DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF; } static BOOL HasFont(const DLGTEMPLATE* pTemplate) { return (DS_SETFONT & (IsDialogEx(pTemplate) ? ((_ATL_DLGTEMPLATEEX*)pTemplate)->style : pTemplate->style)); } static BYTE* GetFontSizeField(const DLGTEMPLATE* pTemplate) { BOOL bDialogEx = IsDialogEx(pTemplate); WORD* pw; if (bDialogEx) pw = (WORD*)((_ATL_DLGTEMPLATEEX*)pTemplate + 1); else pw = (WORD*)(pTemplate + 1); if (*pw == (WORD)-1) // Skip menu name string or ordinal pw += 2; // WORDs else while(*pw++); if (*pw == (WORD)-1) // Skip class name string or ordinal pw += 2; // WORDs else while(*pw++); while (*pw++); // Skip caption string return (BYTE*)pw; } static BOOL GetFont(const DLGTEMPLATE* pTemplate, TCHAR* pszFace, WORD* pFontSize) { USES_CONVERSION; if (!HasFont(pTemplate)) return FALSE; BYTE* pb = GetFontSizeField(pTemplate); *pFontSize = *(WORD*)pb; // Skip over font attributes to get to the font name pb += sizeof(WORD) * (IsDialogEx(pTemplate) ? 3 : 1); _tcscpy(pszFace, W2T((WCHAR*)pb)); return TRUE; } static void GetSizeInDialogUnits(const DLGTEMPLATE* pTemplate, SIZE* pSize) { if (IsDialogEx(pTemplate)) { pSize->cx = ((_ATL_DLGTEMPLATEEX*)pTemplate)->cx; pSize->cy = ((_ATL_DLGTEMPLATEEX*)pTemplate)->cy; } else { pSize->cx = pTemplate->cx; pSize->cy = pTemplate->cy; } } }; ////////////////////////////////////////////////////////////////////////////// // IPropertyPage2Impl template class ATL_NO_VTABLE IPropertyPage2Impl : public IPropertyPageImpl { public: STDMETHOD(EditProperty)(DISPID dispID) { ATLTRACENOTIMPL(_T("IPropertyPage2Impl::EditProperty\n")); } }; ////////////////////////////////////////////////////////////////////////////// // IPerPropertyBrowsingImpl template class ATL_NO_VTABLE IPerPropertyBrowsingImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPerPropertyBrowsingImpl) STDMETHOD(GetDisplayString)(DISPID dispID,BSTR *pBstr) { ATLTRACE(_T("IPerPropertyBrowsingImpl::GetDisplayString\n")); T* pT = static_cast(this); CComVariant var; if (FAILED(CComDispatchDriver::GetProperty(pT, dispID, &var))) { *pBstr = NULL; return S_FALSE; } BSTR bstrTemp = var.bstrVal; if (var.vt != VT_BSTR) { CComVariant varDest; if (FAILED(::VariantChangeType(&varDest, &var, VARIANT_NOVALUEPROP, VT_BSTR))) { *pBstr = NULL; return S_FALSE; } bstrTemp = varDest.bstrVal; } *pBstr = SysAllocString(bstrTemp); return S_OK; } STDMETHOD(MapPropertyToPage)(DISPID dispID, CLSID *pClsid) { ATLTRACE(_T("IPerPropertyBrowsingImpl::MapPropertyToPage\n")); T* pT = static_cast(this); ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap(); _ASSERTE(pMap != NULL); for(int i = 0; pMap[i].pclsidPropPage != NULL; i++) { if (pMap[i].szDesc == NULL) continue; if (pMap[i].dispid == dispID) { _ASSERTE(pMap[i].pclsidPropPage != NULL); *pClsid = *(pMap[i].pclsidPropPage); return S_OK; } } *pClsid = CLSID_NULL; return E_INVALIDARG; } STDMETHOD(GetPredefinedStrings)(DISPID dispID, CALPOLESTR *pCaStringsOut,CADWORD *pCaCookiesOut) { dispID; ATLTRACE(_T("IPerPropertyBrowsingImpl::GetPredefinedStrings\n")); if (pCaStringsOut == NULL || pCaCookiesOut == NULL) return E_POINTER; pCaStringsOut->cElems = 0; pCaStringsOut->pElems = NULL; pCaCookiesOut->cElems = 0; pCaCookiesOut->pElems = NULL; return S_OK; } STDMETHOD(GetPredefinedValue)(DISPID /*dispID*/, DWORD /*dwCookie*/, VARIANT* /*pVarOut*/) { ATLTRACENOTIMPL(_T("IPerPropertyBrowsingImpl::GetPredefinedValue")); } }; ////////////////////////////////////////////////////////////////////////////// // IViewObjectExImpl template class ATL_NO_VTABLE IViewObjectExImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IViewObjectExImpl) // IViewObject // STDMETHOD(Draw)(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw, LPCRECTL prcBounds, LPCRECTL prcWBounds, BOOL (__stdcall * /*pfnContinue*/)(DWORD_PTR dwContinue), DWORD_PTR /*dwContinue*/) { T* pT = static_cast(this); ATLTRACE(_T("IViewObjectExImpl::Draw\n")); return pT->IViewObject_Draw(dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, hdcDraw, prcBounds, prcWBounds); } STDMETHOD(GetColorSet)(DWORD /* dwDrawAspect */,LONG /* lindex */, void* /* pvAspect */, DVTARGETDEVICE* /* ptd */, HDC /* hicTargetDev */, LOGPALETTE** /* ppColorSet */) { ATLTRACENOTIMPL(_T("IViewObjectExImpl::GetColorSet")); } STDMETHOD(Freeze)(DWORD /* dwDrawAspect */, LONG /* lindex */, void* /* pvAspect */,DWORD* /* pdwFreeze */) { ATLTRACENOTIMPL(_T("IViewObjectExImpl::Freeze")); } STDMETHOD(Unfreeze)(DWORD /* dwFreeze */) { ATLTRACENOTIMPL(_T("IViewObjectExImpl::Unfreeze")); } STDMETHOD(SetAdvise)(DWORD /* aspects */, DWORD /* advf */, IAdviseSink* pAdvSink) { T* pT = static_cast(this); ATLTRACE(_T("IViewObjectExImpl::SetAdvise\n")); pT->m_spAdviseSink = pAdvSink; return S_OK; } STDMETHOD(GetAdvise)(DWORD* /* pAspects */, DWORD* /* pAdvf */, IAdviseSink** ppAdvSink) { T* pT = static_cast(this); ATLTRACE(_T("IViewObjectExImpl::GetAdvise\n")); if (ppAdvSink != NULL) { *ppAdvSink = pT->m_spAdviseSink; if (pT->m_spAdviseSink) pT->m_spAdviseSink.p->AddRef(); } return S_OK; } // IViewObject2 // STDMETHOD(GetExtent)(DWORD /* dwDrawAspect */, LONG /* lindex */, DVTARGETDEVICE* /* ptd */, LPSIZEL lpsizel) { T* pT = static_cast(this); ATLTRACE(_T("IViewObjectExImpl::GetExtent\n")); *lpsizel = pT->m_sizeExtent; return S_OK; } // IViewObjectEx // STDMETHOD(GetRect)(DWORD /* dwAspect */, LPRECTL /* pRect */) { ATLTRACENOTIMPL(_T("IViewObjectExImpl::GetRect")); } STDMETHOD(GetViewStatus)(DWORD* pdwStatus) { ATLTRACE(_T("IViewObjectExImpl::GetViewStatus\n")); *pdwStatus = // VIEWSTATUS_DVASPECTOPAQUE | VIEWSTATUS_DVASPECTTRANSPARENT | // VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE; return S_OK; } STDMETHOD(QueryHitPoint)(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG /* lCloseHint */, DWORD *pHitResult) { ATLTRACE(_T("IViewObjectExImpl::QueryHitPoint\n")); if (dwAspect == DVASPECT_CONTENT) { *pHitResult = PtInRect(pRectBounds, ptlLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE; return S_OK; } ATLTRACE(_T("Wrong DVASPECT\n")); return E_FAIL; } STDMETHOD(QueryHitRect)(DWORD dwAspect, LPCRECT pRectBounds, LPCRECT prcLoc, LONG /* lCloseHint */, DWORD* pHitResult) { ATLTRACE(_T("IViewObjectExImpl::QueryHitRect\n")); if (dwAspect == DVASPECT_CONTENT) { RECT rc; *pHitResult = UnionRect(&rc, pRectBounds, prcLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE; return S_OK; } ATLTRACE(_T("Wrong DVASPECT\n")); return E_FAIL; } STDMETHOD(GetNaturalExtent)(DWORD dwAspect, LONG /* lindex */, DVTARGETDEVICE* /* ptd */, HDC /* hicTargetDev */, DVEXTENTINFO* pExtentInfo , LPSIZEL psizel) { T* pT = static_cast(this); ATLTRACE(_T("IViewObjectExImpl::GetNaturalExtent\n")); HRESULT hRes = E_FAIL; if (dwAspect == DVASPECT_CONTENT) { if (pExtentInfo->dwExtentMode == DVEXTENT_CONTENT) { *psizel = pT->m_sizeNatural; hRes = S_OK; } } return hRes; } public: }; ////////////////////////////////////////////////////////////////////////////// // IOleInPlaceObjectWindowlessImpl // template class ATL_NO_VTABLE IOleInPlaceObjectWindowlessImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleInPlaceObjectWindowlessImpl) // IOleWindow // // Change IOleInPlaceActiveObject::GetWindow as well STDMETHOD(GetWindow)(HWND* phwnd) { ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::GetWindow\n")); T* pT = static_cast(this); HRESULT hRes = E_POINTER; if (pT->m_bWasOnceWindowless) return E_FAIL; if (phwnd != NULL) { *phwnd = pT->m_hWnd; hRes = (*phwnd == NULL) ? E_UNEXPECTED : S_OK; } return hRes; } STDMETHOD(ContextSensitiveHelp)(BOOL /* fEnterMode */) { ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::ContextSensitiveHelp")); } // IOleInPlaceObject // STDMETHOD(InPlaceDeactivate)(void) { T* pT = static_cast(this); ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::InPlaceDeactivate\n")); return pT->IOleInPlaceObject_InPlaceDeactivate(); } STDMETHOD(UIDeactivate)(void) { T* pT = static_cast(this); ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::UIDeactivate\n")); return pT->IOleInPlaceObject_UIDeactivate(); } STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip) { T* pT = static_cast(this); ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::SetObjectRects\n")); return pT->IOleInPlaceObject_SetObjectRects(prcPos, prcClip); } STDMETHOD(ReactivateAndUndo)(void) { ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::ReactivateAndUndo")); } // IOleInPlaceObjectWindowless // STDMETHOD(OnWindowMessage)(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) { ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::OnWindowMessage\n")); T* pT = static_cast(this); return (pT->ProcessWindowMessage(pT->m_hWnd, msg, wParam, lParam, *plResult)) ? S_OK : S_FALSE; } STDMETHOD(GetDropTarget)(IDropTarget** /* ppDropTarget */) { ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::GetDropTarget")); } }; ////////////////////////////////////////////////////////////////////////////// // IOleInPlaceActiveObjectImpl // template class ATL_NO_VTABLE IOleInPlaceActiveObjectImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleInPlaceActiveObjectImpl) // IOleWindow // // Change IOleInPlaceObjectWindowless::GetWindow as well STDMETHOD(GetWindow)(HWND *phwnd) { ATLTRACE(_T("IOleInPlaceActiveObjectImpl::GetWindow\n")); T* pT = static_cast(this); HRESULT hRes = E_POINTER; if (pT->m_bWasOnceWindowless) return E_FAIL; if (phwnd != NULL) { *phwnd = pT->m_hWnd; hRes = (*phwnd == NULL) ? E_UNEXPECTED : S_OK; } return hRes; } STDMETHOD(ContextSensitiveHelp)(BOOL /* fEnterMode */) { ATLTRACENOTIMPL(_T("IOleInPlaceActiveObjectImpl::ContextSensitiveHelp")); } // IOleInPlaceActiveObject // STDMETHOD(TranslateAccelerator)(LPMSG /* lpmsg */) { ATLTRACE(_T("IOleInPlaceActiveObjectImpl::TranslateAccelerator\n")); return E_NOTIMPL; } STDMETHOD(OnFrameWindowActivate)(BOOL /* fActivate */) { ATLTRACE(_T("IOleInPlaceActiveObjectImpl::OnFrameWindowActivate\n")); return S_OK; } STDMETHOD(OnDocWindowActivate)(BOOL /* fActivate */) { ATLTRACE(_T("IOleInPlaceActiveObjectImpl::OnDocWindowActivate\n")); return S_OK; } STDMETHOD(ResizeBorder)(LPCRECT /* prcBorder */, IOleInPlaceUIWindow* /* pUIWindow */, BOOL /* fFrameWindow */) { ATLTRACE(_T("IOleInPlaceActiveObjectImpl::ResizeBorder\n")); return S_OK; } STDMETHOD(EnableModeless)(BOOL /* fEnable */) { ATLTRACE(_T("IOleInPlaceActiveObjectImpl::EnableModeless\n")); return S_OK; } }; ////////////////////////////////////////////////////////////////////////////// // ISpecifyPropertyPagesImpl template class ATL_NO_VTABLE ISpecifyPropertyPagesImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(ISpecifyPropertyPagesImpl) // ISpecifyPropertyPages // STDMETHOD(GetPages)(CAUUID* pPages) { ATLTRACE(_T("ISpecifyPropertyPagesImpl::GetPages\n")); T* pT = static_cast(this); ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap(); return pT->ISpecifyPropertyPages_GetPages(pPages, pMap); } }; ////////////////////////////////////////////////////////////////////////////// // IPointerInactiveImpl template class ATL_NO_VTABLE IPointerInactiveImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPointerInactiveImpl) // IPointerInactive // STDMETHOD(GetActivationPolicy)(DWORD *pdwPolicy) { ATLTRACENOTIMPL(_T("IPointerInactiveImpl::GetActivationPolicy")); } STDMETHOD(OnInactiveMouseMove)(LPCRECT pRectBounds, long x, long y, DWORD dwMouseMsg) { ATLTRACENOTIMPL(_T("IPointerInactiveImpl::OnInactiveMouseMove")); } STDMETHOD(OnInactiveSetCursor)(LPCRECT pRectBounds, long x, long y, DWORD dwMouseMsg, BOOL fSetAlways) { ATLTRACENOTIMPL(_T("IPointerInactiveImpl::OnInactiveSetCursor")); } }; ////////////////////////////////////////////////////////////////////////////// // IRunnableObjectImpl template class ATL_NO_VTABLE IRunnableObjectImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IRunnableObjectImpl) // IRunnableObject // STDMETHOD(GetRunningClass)(LPCLSID lpClsid) { ATLTRACE(_T("IRunnableObjectImpl::GetRunningClass\n")); T* pT = static_cast(this); *lpClsid = GUID_NULL; return E_UNEXPECTED; } STDMETHOD(Run)(LPBINDCTX) { ATLTRACE(_T("IRunnableObjectImpl::Run\n")); return S_OK; } virtual BOOL STDMETHODCALLTYPE IsRunning() { ATLTRACE(_T("IRunnableObjectImpl::IsRunning\n")); return TRUE; } STDMETHOD(LockRunning)(BOOL /*fLock*/, BOOL /*fLastUnlockCloses*/) { ATLTRACE(_T("IRunnableObjectImpl::LockRunning\n")); return S_OK; } STDMETHOD(SetContainedObject)(BOOL /*fContained*/) { ATLTRACE(_T("IRunnableObjectImpl::SetContainedObject\n")); return S_OK; } }; ////////////////////////////////////////////////////////////////////////////// // IDataObjectImpl template class ATL_NO_VTABLE IDataObjectImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IDataObjectImpl) // IDataObject // STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium) { ATLTRACE(_T("IDataObjectImpl::GetData\n")); T* pT = (T*) this; return pT->IDataObject_GetData(pformatetcIn, pmedium); } STDMETHOD(GetDataHere)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */) { ATLTRACENOTIMPL(_T("IDataObjectImpl::GetDataHere")); } STDMETHOD(QueryGetData)(FORMATETC* /* pformatetc */) { ATLTRACENOTIMPL(_T("IDataObjectImpl::QueryGetData")); } STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */) { ATLTRACENOTIMPL(_T("IDataObjectImpl::GetCanonicalFormatEtc")); } STDMETHOD(SetData)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */) { ATLTRACENOTIMPL(_T("IDataObjectImpl::SetData")); } STDMETHOD(EnumFormatEtc)(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */) { ATLTRACENOTIMPL(_T("IDataObjectImpl::EnumFormatEtc")); } STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection) { ATLTRACE(_T("IDataObjectImpl::DAdvise\n")); T* pT = static_cast(this); HRESULT hr = S_OK; if (pT->m_spDataAdviseHolder == NULL) hr = CreateDataAdviseHolder(&pT->m_spDataAdviseHolder); if (hr == S_OK) hr = pT->m_spDataAdviseHolder->Advise((IDataObject*)this, pformatetc, advf, pAdvSink, pdwConnection); return hr; } STDMETHOD(DUnadvise)(DWORD dwConnection) { ATLTRACE(_T("IDataObjectImpl::DUnadvise\n")); T* pT = static_cast(this); HRESULT hr = S_OK; if (pT->m_spDataAdviseHolder == NULL) hr = OLE_E_NOCONNECTION; else hr = pT->m_spDataAdviseHolder->Unadvise(dwConnection); return hr; } STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise) { ATLTRACE(_T("IDataObjectImpl::EnumDAdvise\n")); T* pT = static_cast(this); HRESULT hr = E_FAIL; if (pT->m_spDataAdviseHolder != NULL) hr = pT->m_spDataAdviseHolder->EnumAdvise(ppenumAdvise); return hr; } }; ////////////////////////////////////////////////////////////////////////////// // IPropertyNotifySinkCP template class ATL_NO_VTABLE IPropertyNotifySinkCP : public IConnectionPointImpl { public: typedef CFirePropNotifyEvent _ATL_PROP_NOTIFY_EVENT_CLASS; }; ////////////////////////////////////////////////////////////////////////////// // IObjectSafety // template class ATL_NO_VTABLE IObjectSafetyImpl { public: IObjectSafetyImpl() { m_dwSafety = 0; } // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IObjectSafetyImpl) // IObjectSafety // STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions) { ATLTRACE(_T("IObjectSafetyImpl::GetInterfaceSafetyOptions\n")); if (pdwSupportedOptions == NULL || pdwEnabledOptions == NULL) return E_POINTER; HRESULT hr = S_OK; if (riid == IID_IDispatch) { *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; *pdwEnabledOptions = m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER; } else { *pdwSupportedOptions = 0; *pdwEnabledOptions = 0; hr = E_NOINTERFACE; } return hr; } STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions) { ATLTRACE(_T("IObjectSafetyImpl::SetInterfaceSafetyOptions\n")); // If we're being asked to set our safe for scripting option then oblige if (riid == IID_IDispatch) { // Store our current safety level to return in GetInterfaceSafetyOptions m_dwSafety = dwEnabledOptions & dwOptionSetMask; return S_OK; } return E_NOINTERFACE; } DWORD m_dwSafety; }; template class ATL_NO_VTABLE IOleLinkImpl { // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleLinkImpl) STDMETHOD(SetUpdateOptions)(DWORD /* dwUpdateOpt */) { ATLTRACENOTIMPL(_T("IOleLinkImpl::SetUpdateOptions")); } STDMETHOD(GetUpdateOptions)(DWORD* /* pdwUpdateOpt */) { ATLTRACENOTIMPL(_T("IOleLinkImpl::GetUpdateOptions")); } STDMETHOD(SetSourceMoniker)(IMoniker* /* pmk */, REFCLSID /* rclsid */) { ATLTRACENOTIMPL(_T("IOleLinkImpl::SetSourceMoniker")); } STDMETHOD(GetSourceMoniker)(IMoniker** /* ppmk */) { ATLTRACENOTIMPL(_T("IOleLinkImpl::GetSourceMoniker")); }; STDMETHOD(SetSourceDisplayName)(LPCOLESTR /* pszStatusText */) { ATLTRACENOTIMPL(_T("IOleLinkImpl::SetSourceDisplayName")); } STDMETHOD(GetSourceDisplayName)(LPOLESTR *ppszDisplayName) { ATLTRACE(_T("IOleLink::GetSourceDisplayName\n")); *ppszDisplayName = NULL; return E_FAIL; } STDMETHOD(BindToSource)(DWORD /* bindflags */, IBindCtx* /* pbc */) { ATLTRACENOTIMPL(_T("IOleLinkImpl::BindToSource\n")); }; STDMETHOD(BindIfRunning)() { ATLTRACE(_T("IOleLinkImpl::BindIfRunning\n")); return S_OK; }; STDMETHOD(GetBoundSource)(IUnknown** /* ppunk */) { ATLTRACENOTIMPL(_T("IOleLinkImpl::GetBoundSource")); }; STDMETHOD(UnbindSource)() { ATLTRACENOTIMPL(_T("IOleLinkImpl::UnbindSource")); }; STDMETHOD(Update)(IBindCtx* /* pbc */) { ATLTRACENOTIMPL(_T("IOleLinkImpl::Update")); }; }; template class ATL_NO_VTABLE IBindStatusCallbackImpl { public: // IUnknown // STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0; _ATL_DEBUG_ADDREF_RELEASE_IMPL(IBindStatusCallbackImpl) // IBindStatusCallback // STDMETHOD(OnStartBinding)(DWORD /* dwReserved */, IBinding *pBinding) { ATLTRACE(_T("IBindStatusCallbackImpl::OnStartBinding\n")); return S_OK; } STDMETHOD(GetPriority)(LONG* /* pnPriority */) { ATLTRACENOTIMPL(_T("IBindStatusCallbackImpl::GetPriority")); } STDMETHOD(OnLowResource)(DWORD /* reserved */) { ATLTRACE(_T("IBindStatusCallbackImpl::OnLowResource\n")); return S_OK; } STDMETHOD(OnProgress)(ULONG /* ulProgress */, ULONG /* ulProgressMax */, ULONG /* ulStatusCode */, LPCWSTR /* szStatusText */) { ATLTRACE(_T("IBindStatusCallbackImpl::OnProgress\n")); return S_OK; } STDMETHOD(OnStopBinding)(HRESULT /* hresult */, LPCWSTR /* szError */) { ATLTRACE(_T("IBindStatusCallbackImpl::OnStopBinding\n")); return S_OK; } STDMETHOD(GetBindInfo)(DWORD* /* pgrfBINDF */, BINDINFO* /* pBindInfo */) { ATLTRACE(_T("IBindStatusCallbackImpl::GetBindInfo\n")); return S_OK; } STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed) { ATLTRACE(_T("IBindStatusCallbackImpl::OnDataAvailable\n")); return S_OK; } STDMETHOD(OnObjectAvailable)(REFIID /* riid */, IUnknown* /* punk */) { ATLTRACE(_T("IBindStatusCallbackImpl::OnObjectAvailable\n")); return S_OK; } }; template class ATL_NO_VTABLE CBindStatusCallback : public CComObjectRootEx, public IBindStatusCallbackImpl { typedef void (T::*ATL_PDATAAVAILABLE)(CBindStatusCallback* pbsc, BYTE* pBytes, DWORD dwSize); public: BEGIN_COM_MAP(CBindStatusCallback) COM_INTERFACE_ENTRY_IID(IID_IBindStatusCallback, IBindStatusCallbackImpl) END_COM_MAP() CBindStatusCallback() { m_pT = NULL; m_pFunc = NULL; } ~CBindStatusCallback() { ATLTRACE(_T("~CBindStatusCallback\n")); } STDMETHOD(OnStartBinding)(DWORD dwReserved, IBinding *pBinding) { ATLTRACE(_T("CBindStatusCallback::OnStartBinding\n")); m_spBinding = pBinding; return S_OK; } STDMETHOD(GetPriority)(LONG *pnPriority) { ATLTRACENOTIMPL(_T("CBindStatusCallback::GetPriority")); } STDMETHOD(OnLowResource)(DWORD reserved) { ATLTRACENOTIMPL(_T("CBindStatusCallback::OnLowResource")); } STDMETHOD(OnProgress)(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText) { ATLTRACENOTIMPL(_T("CBindStatusCallback::OnProgress")); } STDMETHOD(OnStopBinding)(HRESULT hresult, LPCWSTR szError) { ATLTRACE(_T("CBindStatusCallback::OnStopBinding\n")); m_spBinding.Release(); m_spBindCtx.Release(); m_spMoniker.Release(); return S_OK; } STDMETHOD(GetBindInfo)(DWORD *pgrfBINDF, BINDINFO *pbindInfo) { ATLTRACE(_T("CBindStatusCallback::GetBindInfo\n")); if (pbindInfo==NULL || pbindInfo->cbSize==0 || pgrfBINDF==NULL) return E_INVALIDARG; *pgrfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_GETNEWESTVERSION | BINDF_NOWRITECACHE; ULONG cbSize = pbindInfo->cbSize; // remember incoming cbSize memset(pbindInfo, 0, cbSize); // zero out structure pbindInfo->cbSize = cbSize; // restore cbSize pbindInfo->dwBindVerb = BINDVERB_GET; // set verb return S_OK; } STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed) { ATLTRACE(_T("CBindStatusCallback::OnDataAvailable\n")); HRESULT hr = S_OK; // Get the Stream passed if (BSCF_FIRSTDATANOTIFICATION & grfBSCF) { if (!m_spStream && pstgmed->tymed == TYMED_ISTREAM) m_spStream = pstgmed->pstm; } DWORD dwRead = dwSize - m_dwTotalRead; // Minimum amount available that hasn't been read DWORD dwActuallyRead = 0; // Placeholder for amount read during this pull // If there is some data to be read then go ahead and read them if (m_spStream) { if (dwRead > 0) { BYTE* pBytes = NULL; ATLTRY(pBytes = new BYTE[dwRead + 1]); if (pBytes == NULL) return S_FALSE; hr = m_spStream->Read(pBytes, dwRead, &dwActuallyRead); if (SUCCEEDED(hr)) { pBytes[dwActuallyRead] = 0; if (dwActuallyRead>0) { (m_pT->*m_pFunc)(this, pBytes, dwActuallyRead); m_dwTotalRead += dwActuallyRead; } } delete[] pBytes; } } if (BSCF_LASTDATANOTIFICATION & grfBSCF) m_spStream.Release(); return hr; } STDMETHOD(OnObjectAvailable)(REFIID riid, IUnknown *punk) { ATLTRACENOTIMPL(_T("CBindStatusCallback::OnObjectAvailable")); } HRESULT _StartAsyncDownload(BSTR bstrURL, IUnknown* pUnkContainer, BOOL bRelative) { m_dwTotalRead = 0; m_dwAvailableToRead = 0; HRESULT hr = S_OK; CComQIPtr spServiceProvider(pUnkContainer); CComPtr spBindHost; CComPtr spStream; if (spServiceProvider) spServiceProvider->QueryService(SID_IBindHost, IID_IBindHost, (void**)&spBindHost); if (spBindHost == NULL) { if (bRelative) return E_NOINTERFACE; // relative asked for, but no IBindHost hr = CreateURLMoniker(NULL, bstrURL, &m_spMoniker); if (SUCCEEDED(hr)) hr = CreateBindCtx(0, &m_spBindCtx); if (SUCCEEDED(hr)) hr = RegisterBindStatusCallback(m_spBindCtx, reinterpret_cast(static_cast*>(this)), 0, 0L); else m_spMoniker.Release(); if (SUCCEEDED(hr)) hr = m_spMoniker->BindToStorage(m_spBindCtx, 0, IID_IStream, (void**)&spStream); } else { hr = CreateBindCtx(0, &m_spBindCtx); if (SUCCEEDED(hr)) hr = RegisterBindStatusCallback(m_spBindCtx, reinterpret_cast(static_cast*>(this)), 0, 0L); if (SUCCEEDED(hr)) { if (bRelative) hr = spBindHost->CreateMoniker(bstrURL, m_spBindCtx, &m_spMoniker, 0); else hr = CreateURLMoniker(NULL, bstrURL, &m_spMoniker); } if (SUCCEEDED(hr)) { hr = spBindHost->MonikerBindToStorage(m_spMoniker, NULL, reinterpret_cast(static_cast*>(this)), IID_IStream, (void**)&spStream); ATLTRACE(_T("Bound")); } } return hr; } HRESULT StartAsyncDownload(T* pT, ATL_PDATAAVAILABLE pFunc, BSTR bstrURL, IUnknown* pUnkContainer = NULL, BOOL bRelative = FALSE) { m_pT = pT; m_pFunc = pFunc; return _StartAsyncDownload(bstrURL, pUnkContainer, bRelative); } static HRESULT Download(T* pT, ATL_PDATAAVAILABLE pFunc, BSTR bstrURL, IUnknown* pUnkContainer = NULL, BOOL bRelative = FALSE) { CComObject > *pbsc; HRESULT hRes = CComObject >::CreateInstance(&pbsc); if (FAILED(hRes)) return hRes; return pbsc->StartAsyncDownload(pT, pFunc, bstrURL, pUnkContainer, bRelative); } CComPtr m_spMoniker; CComPtr m_spBindCtx; CComPtr m_spBinding; CComPtr m_spStream; T* m_pT; ATL_PDATAAVAILABLE m_pFunc; DWORD m_dwTotalRead; DWORD m_dwAvailableToRead; }; #define IMPLEMENT_STOCKPROP(type, fname, pname, dispid) \ HRESULT STDMETHODCALLTYPE put_##fname(type pname) \ { \ T* pT = (T*) this; \ if (pT->FireOnRequestEdit(dispid) == S_FALSE) \ return S_FALSE; \ pT->m_##pname = pname; \ pT->m_bRequiresSave = TRUE; \ pT->FireOnChanged(dispid); \ pT->FireViewChange(); \ return S_OK; \ } \ HRESULT STDMETHODCALLTYPE get_##fname(type* p##pname) \ { \ T* pT = (T*) this; \ *p##pname = pT->m_##pname; \ return S_OK; \ } #define IMPLEMENT_BOOL_STOCKPROP(fname, pname, dispid) \ HRESULT STDMETHODCALLTYPE put_##fname(VARIANT_BOOL pname) \ { \ T* pT = (T*) this; \ if (pT->FireOnRequestEdit(dispid) == S_FALSE) \ return S_FALSE; \ pT->m_##pname = pname; \ pT->m_bRequiresSave = TRUE; \ pT->FireOnChanged(dispid); \ pT->FireViewChange(); \ return S_OK; \ } \ HRESULT STDMETHODCALLTYPE get_##fname(VARIANT_BOOL* p##pname) \ { \ T* pT = (T*) this; \ *p##pname = pT->m_##pname ? VARIANT_TRUE : VARIANT_FALSE; \ return S_OK; \ } #define IMPLEMENT_BSTR_STOCKPROP(fname, pname, dispid) \ HRESULT STDMETHODCALLTYPE put_##fname(BSTR pname) \ { \ T* pT = (T*) this; \ if (pT->FireOnRequestEdit(dispid) == S_FALSE) \ return S_FALSE; \ *(&(pT->m_##pname)) = SysAllocString(pname); \ pT->m_bRequiresSave = TRUE; \ pT->FireOnChanged(dispid); \ pT->FireViewChange(); \ return S_OK; \ } \ HRESULT STDMETHODCALLTYPE get_##fname(BSTR* p##pname) \ { \ T* pT = (T*) this; \ *p##pname = SysAllocString(pT->m_##pname); \ return S_OK; \ } template < class T, class InterfaceName, const IID* piid, const GUID* plibid> class ATL_NO_VTABLE CStockPropImpl : public IDispatchImpl< InterfaceName, piid, plibid > { public: // Font HRESULT STDMETHODCALLTYPE put_Font(IFontDisp* pFont) { T* pT = (T*) this; if (pT->FireOnRequestEdit(DISPID_FONT) == S_FALSE) return S_FALSE; pT->m_pFont = 0; if (pFont) { CComQIPtr p(pFont); if (p) { CComPtr pFont; p->Clone(&pFont); if (pFont) pFont->QueryInterface(IID_IFontDisp, (void**) &pT->m_pFont); } } pT->m_bRequiresSave = TRUE; pT->FireOnChanged(DISPID_FONT); pT->FireViewChange(); return S_OK; } HRESULT STDMETHODCALLTYPE putref_Font(IFontDisp* pFont) { T* pT = (T*) this; if (pT->FireOnRequestEdit(DISPID_FONT) == S_FALSE) return S_FALSE; pT->m_pFont = pFont; pT->m_bRequiresSave = TRUE; pT->FireOnChanged(DISPID_FONT); pT->FireViewChange(); return S_OK; } HRESULT STDMETHODCALLTYPE get_Font(IFontDisp** ppFont) { T* pT = (T*) this; *ppFont = pT->m_pFont; if (*ppFont != NULL) (*ppFont)->AddRef(); return S_OK; } // Picture HRESULT STDMETHODCALLTYPE put_Picture(IPictureDisp* pPicture) { T* pT = (T*) this; if (pT->FireOnRequestEdit(DISPID_PICTURE) == S_FALSE) return S_FALSE; pT->m_pPicture = 0; if (pPicture) { CComQIPtr p(pPicture); if (p) { ULARGE_INTEGER l; p->GetSizeMax(&l); HGLOBAL hGlob = GlobalAlloc(GHND, l.LowPart); if (hGlob) { CComPtr spStream; CreateStreamOnHGlobal(hGlob, TRUE, &spStream); if (spStream) { if (SUCCEEDED(p->Save(spStream, FALSE))) { LARGE_INTEGER l; l.QuadPart = 0; spStream->Seek(l, STREAM_SEEK_SET, NULL); OleLoadPicture(spStream, l.LowPart, FALSE, IID_IPictureDisp, (void**)&pT->m_pPicture); } spStream.Release(); } GlobalFree(hGlob); } } } pT->m_bRequiresSave = TRUE; pT->FireOnChanged(DISPID_PICTURE); pT->FireViewChange(); return S_OK; } HRESULT STDMETHODCALLTYPE putref_Picture(IPictureDisp* pPicture) { T* pT = (T*) this; if (pT->FireOnRequestEdit(DISPID_PICTURE) == S_FALSE) return S_FALSE; pT->m_pPicture = pPicture; pT->m_bRequiresSave = TRUE; pT->FireOnChanged(DISPID_PICTURE); pT->FireViewChange(); return S_OK; } HRESULT STDMETHODCALLTYPE get_Picture(IPictureDisp** ppPicture) { T* pT = (T*) this; *ppPicture = pT->m_pPicture; if (*ppPicture != NULL) (*ppPicture)->AddRef(); return S_OK; } // MouseIcon HRESULT STDMETHODCALLTYPE put_MouseIcon(IPictureDisp* pPicture) { T* pT = (T*) this; if (pT->FireOnRequestEdit(DISPID_MOUSEICON) == S_FALSE) return S_FALSE; pT->m_pMouseIcon = 0; if (pPicture) { CComQIPtr p(pPicture); if (p) { ULARGE_INTEGER l; p->GetSizeMax(&l); HGLOBAL hGlob = GlobalAlloc(GHND, l.LowPart); if (hGlob) { CComPtr spStream; CreateStreamOnHGlobal(hGlob, TRUE, &spStream); if (spStream) { if (SUCCEEDED(p->Save(spStream, FALSE))) { LARGE_INTEGER l; l.QuadPart = 0; spStream->Seek(l, STREAM_SEEK_SET, NULL); OleLoadPicture(spStream, l.LowPart, FALSE, IID_IPictureDisp, (void**)&pT->m_pMouseIcon); } spStream.Release(); } GlobalFree(hGlob); } } } pT->m_bRequiresSave = TRUE; pT->FireOnChanged(DISPID_MOUSEICON); pT->FireViewChange(); return S_OK; } HRESULT STDMETHODCALLTYPE putref_MouseIcon(IPictureDisp* pPicture) { T* pT = (T*) this; if (pT->FireOnRequestEdit(DISPID_MOUSEICON) == S_FALSE) return S_FALSE; pT->m_pMouseIcon = pPicture; pT->m_bRequiresSave = TRUE; pT->FireOnChanged(DISPID_MOUSEICON); pT->FireViewChange(); return S_OK; } HRESULT STDMETHODCALLTYPE get_MouseIcon(IPictureDisp** ppPicture) { T* pT = (T*) this; *ppPicture = pT->m_pMouseIcon; if (*ppPicture != NULL) (*ppPicture)->AddRef(); return S_OK; } IMPLEMENT_STOCKPROP(OLE_COLOR, BackColor, clrBackColor, DISPID_BACKCOLOR) IMPLEMENT_STOCKPROP(OLE_COLOR, BorderColor, clrBorderColor, DISPID_BORDERCOLOR) IMPLEMENT_STOCKPROP(OLE_COLOR, FillColor, clrFillColor, DISPID_FILLCOLOR) IMPLEMENT_STOCKPROP(OLE_COLOR, ForeColor, clrForeColor, DISPID_FORECOLOR) IMPLEMENT_BOOL_STOCKPROP(AutoSize, bAutoSize, DISPID_AUTOSIZE) IMPLEMENT_BOOL_STOCKPROP(Valid, bValid, DISPID_VALID) IMPLEMENT_BOOL_STOCKPROP(Enabled, bEnabled, DISPID_ENABLED) IMPLEMENT_BOOL_STOCKPROP(TabStop, bTabStop, DISPID_TABSTOP) IMPLEMENT_BOOL_STOCKPROP(BorderVisible, bBorderVisible, DISPID_BORDERVISIBLE) IMPLEMENT_BSTR_STOCKPROP(Text, bstrText, DISPID_TEXT) IMPLEMENT_BSTR_STOCKPROP(Caption, bstrCaption, DISPID_CAPTION) HRESULT STDMETHODCALLTYPE put_Window(LONG /*hWnd*/) { return E_FAIL; } HRESULT STDMETHODCALLTYPE get_Window(LONG* phWnd) { T* pT = (T*) this; *phWnd = (LONG)(LONG_PTR)pT->m_hWnd; return S_OK; } IMPLEMENT_STOCKPROP(long, BackStyle, nBackStyle, DISPID_BACKSTYLE) IMPLEMENT_STOCKPROP(long, BorderStyle, nBorderStyle, DISPID_BORDERSTYLE) IMPLEMENT_STOCKPROP(long, BorderWidth, nBorderWidth, DISPID_BORDERWIDTH) IMPLEMENT_STOCKPROP(long, DrawMode, nDrawMode, DISPID_DRAWMODE) IMPLEMENT_STOCKPROP(long, DrawStyle, nDrawStyle, DISPID_DRAWSTYLE) IMPLEMENT_STOCKPROP(long, DrawWidth, nDrawWidth, DISPID_DRAWWIDTH) IMPLEMENT_STOCKPROP(long, FillStyle, nFillStyle, DISPID_FILLSTYLE) IMPLEMENT_STOCKPROP(long, Appearance, nAppearance, DISPID_APPEARANCE) IMPLEMENT_STOCKPROP(long, MousePointer, nMousePointer, DISPID_MOUSEPOINTER) IMPLEMENT_STOCKPROP(long, ReadyState, nReadyState, DISPID_READYSTATE) }; #ifndef ATL_NO_NAMESPACE }; //namespace ATL #endif #endif // __ATLCTL_H__