home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Internet 2000 May / MICD_2000_05.iso / CBuilder5 / INSTALL / DATA1.CAB / Program_Built_Files / Include / Atl / atlctl.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-01  |  94.4 KB  |  3,385 lines

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10.  
  11. #ifndef __ATLCTL_H__
  12. #define __ATLCTL_H__
  13.  
  14. #ifndef __cplusplus
  15.     #error ATL requires C++ compilation (use a .cpp suffix)
  16. #endif
  17.  
  18. #include "atlwin.h"
  19.  
  20. #include <objsafe.h>
  21. #include <urlmon.h>
  22.  
  23. #ifndef __BORLANDC__
  24. #ifdef _BCB_ATL_DEBUG
  25. #define _DEBUG
  26. #endif
  27. #pragma comment(lib, "gdi32.lib")
  28. #pragma comment(lib, "urlmon.lib")
  29. #endif
  30.  
  31.  
  32. #define DECLARE_VIEW_STATUS(statusFlags) \
  33.     DWORD _GetViewStatus() \
  34.     { \
  35.         return statusFlags; \
  36.     }
  37.  
  38. // Include GUIDs for the new stock property dialogs contained in the dll MSStkProp.DLL
  39. #include "msstkppg.h"
  40. #include "atliface.h"
  41. #define CLSID_MSStockFont CLSID_StockFontPage
  42. #define CLSID_MSStockColor CLSID_StockColorPage
  43. #define CLSID_MSStockPicture CLSID_StockPicturePage
  44.  
  45. struct ATL_DRAWINFO
  46. {
  47.     UINT cbSize;
  48.     DWORD dwDrawAspect;
  49.     LONG lindex;
  50.     DVTARGETDEVICE* ptd;
  51.     HDC hicTargetDev;
  52.     HDC hdcDraw;
  53.     LPCRECTL prcBounds; //Rectangle in which to draw
  54.     LPCRECTL prcWBounds; //WindowOrg and Ext if metafile
  55.     BOOL bOptimize;
  56.     BOOL bZoomed;
  57.     BOOL bRectInHimetric;
  58.     SIZEL ZoomNum;      //ZoomX = ZoomNum.cx/ZoomNum.cy
  59.     SIZEL ZoomDen;
  60. };
  61.  
  62. namespace ATL
  63. {
  64.  
  65. #pragma pack(push, _ATL_PACKING)
  66.  
  67. // Forward declarations
  68. //
  69. class ATL_NO_VTABLE CComControlBase;
  70. template <class T, class WinBase> class CComControl;
  71.  
  72. //////////////////////////////////////////////////////////////////////////////
  73. // CFirePropNotifyEvent
  74.  
  75.  
  76. // Helper functions for safely communicating with objects who sink IPropertyNotifySink
  77. class CFirePropNotifyEvent
  78. {
  79. public:
  80.     // Ask any objects sinking the IPropertyNotifySink notification if it is ok to edit a specified property
  81.     static HRESULT FireOnRequestEdit(IUnknown* pUnk, DISPID dispID)
  82.     {
  83.         CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pCPC(pUnk);
  84.         if (!pCPC)
  85.             return S_OK;
  86.         CComPtr<IConnectionPoint> pCP;
  87.         pCPC->FindConnectionPoint(IID_IPropertyNotifySink, &pCP);
  88.         if (!pCP)
  89.             return S_OK;
  90.         CComPtr<IEnumConnections> pEnum;
  91.  
  92.         if (FAILED(pCP->EnumConnections(&pEnum)))
  93.             return S_OK;
  94.         CONNECTDATA cd;
  95.         while (pEnum->Next(1, &cd, NULL) == S_OK)
  96.         {
  97.             if (cd.pUnk)
  98.             {
  99.                 HRESULT hr = S_OK;
  100.                 CComQIPtr<IPropertyNotifySink, &IID_IPropertyNotifySink> pSink(cd.pUnk);
  101.                 if (pSink)
  102.                     hr = pSink->OnRequestEdit(dispID);
  103.                 cd.pUnk->Release();
  104.                 if (hr == S_FALSE)
  105.                     return S_FALSE;
  106.             }
  107.         }
  108.         return S_OK;
  109.     }
  110.     // Notify any objects sinking the IPropertyNotifySink notification that a property has changed
  111.     static HRESULT FireOnChanged(IUnknown* pUnk, DISPID dispID)
  112.     {
  113.         CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pCPC(pUnk);
  114.         if (!pCPC)
  115.             return S_OK;
  116.         CComPtr<IConnectionPoint> pCP;
  117.         pCPC->FindConnectionPoint(IID_IPropertyNotifySink, &pCP);
  118.         if (!pCP)
  119.             return S_OK;
  120.         CComPtr<IEnumConnections> pEnum;
  121.  
  122.         if (FAILED(pCP->EnumConnections(&pEnum)))
  123.             return S_OK;
  124.         CONNECTDATA cd;
  125.         while (pEnum->Next(1, &cd, NULL) == S_OK)
  126.         {
  127.             if (cd.pUnk)
  128.             {
  129.                 CComQIPtr<IPropertyNotifySink, &IID_IPropertyNotifySink> pSink(cd.pUnk);
  130.                 if (pSink)
  131.                     pSink->OnChanged(dispID);
  132.                 cd.pUnk->Release();
  133.             }
  134.         }
  135.         return S_OK;
  136.     }
  137. };
  138.  
  139.  
  140. //////////////////////////////////////////////////////////////////////////////
  141. // CComControlBase
  142.  
  143. // Holds the essential data members for an ActiveX control and useful helper functions
  144. class ATL_NO_VTABLE CComControlBase
  145. {
  146. public:
  147.     CComControlBase(HWND& h) : m_hWndCD(h)
  148.     {
  149.         memset(this, 0, sizeof(CComControlBase));
  150.         m_phWndCD = &h;
  151.         m_sizeExtent.cx = 2*2540;
  152.         m_sizeExtent.cy = 2*2540;
  153.         m_sizeNatural = m_sizeExtent;
  154.     }
  155.     ~CComControlBase()
  156.     {
  157.         if (m_hWndCD != NULL)
  158.             ::DestroyWindow(m_hWndCD);
  159.         ATLTRACE2(atlTraceControls,2,_T("Control Destroyed\n"));
  160.     }
  161.  
  162. // methods
  163. public:
  164.     // Control helper functions can go here non-virtuals only please
  165.  
  166.     // Mark the control 'dirty' so the container will save it
  167.     void SetDirty(BOOL bDirty)
  168.     {
  169.         m_bRequiresSave = bDirty;
  170.     }
  171.     // Obtain the dirty state for the control 
  172.     BOOL GetDirty()
  173.     {
  174.         return m_bRequiresSave ? TRUE : FALSE;
  175.     }
  176.     // Get the zoom factor (numerator & denominator) which is factor of the natural extent
  177.     void GetZoomInfo(ATL_DRAWINFO& di);
  178.     // Sends a notification that the moniker for the control has changed
  179.     HRESULT SendOnRename(IMoniker *pmk)
  180.     {
  181.         HRESULT hRes = S_OK;
  182.         if (m_spOleAdviseHolder)
  183.             hRes = m_spOleAdviseHolder->SendOnRename(pmk);
  184.         return hRes;
  185.     }
  186.     // Sends a notification that the control has just saved its data
  187.     HRESULT SendOnSave()
  188.     {
  189.         HRESULT hRes = S_OK;
  190.         if (m_spOleAdviseHolder)
  191.             hRes = m_spOleAdviseHolder->SendOnSave();
  192.         return hRes;
  193.     }
  194.     // Sends a notification that the control has closed its advisory sinks
  195.     HRESULT SendOnClose()
  196.     {
  197.         HRESULT hRes = S_OK;
  198.         if (m_spOleAdviseHolder)
  199.             hRes = m_spOleAdviseHolder->SendOnClose();
  200.         return hRes;
  201.     }
  202.     // Sends a notification that the control's data has changed
  203.     HRESULT SendOnDataChange(DWORD advf = 0);
  204.     // Sends a notification that the control's representation has changed
  205.     HRESULT SendOnViewChange(DWORD dwAspect, LONG lindex = -1)
  206.     {
  207.         if (m_spAdviseSink)
  208.             m_spAdviseSink->OnViewChange(dwAspect, lindex);
  209.         return S_OK;
  210.     }
  211.     // Sends a notification to the container that the control has received focus
  212.     LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  213.     {
  214.         if (m_bInPlaceActive)
  215.         {
  216.             CComPtr<IOleObject> pOleObject;
  217.             ControlQueryInterface(IID_IOleObject, (void**)&pOleObject);
  218.             if (pOleObject != NULL)
  219.                 pOleObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_spClientSite, 0, m_hWndCD, &m_rcPos);
  220.             CComQIPtr<IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  221.             if (m_bInPlaceActive && spSite != NULL)
  222.                 spSite->OnFocus(TRUE);
  223.         }
  224.         bHandled = FALSE;
  225.         return 1;
  226.     }
  227.     LRESULT OnKillFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  228.     {
  229.         CComQIPtr<IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  230.         if (m_bInPlaceActive && spSite != NULL && !::IsChild(m_hWndCD, ::GetFocus()))
  231.             spSite->OnFocus(FALSE);
  232.         bHandled = FALSE;
  233.         return 1;
  234.     }
  235.     LRESULT OnMouseActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  236.     {
  237.         BOOL bUserMode = TRUE;
  238.         HRESULT hRet = GetAmbientUserMode(bUserMode);
  239.         // UI activate if in user mode only
  240.         // allow activation if we can't determine mode
  241.         if (FAILED(hRet) || bUserMode)
  242.         {
  243.             CComPtr<IOleObject> pOleObject;
  244.             ControlQueryInterface(IID_IOleObject, (void**)&pOleObject);
  245.             if (pOleObject != NULL)
  246.                 pOleObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_spClientSite, 0, m_hWndCD, &m_rcPos);
  247.         }
  248.         bHandled = FALSE;
  249.         return 1;
  250.     }
  251.     BOOL PreTranslateAccelerator(LPMSG /*pMsg*/, HRESULT& /*hRet*/)
  252.     {
  253.         return FALSE;
  254.     }
  255.  
  256.     HRESULT GetAmbientProperty(DISPID dispid, VARIANT& var)
  257.     {
  258.         HRESULT hRes = E_FAIL;
  259.         if (m_spAmbientDispatch.p != NULL)
  260.             hRes = m_spAmbientDispatch.GetProperty(dispid, &var);
  261.         return hRes;
  262.     }
  263.     HRESULT GetAmbientAppearance(short& nAppearance)
  264.     {
  265.         CComVariant var;
  266.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_APPEARANCE, var);
  267.         ATLASSERT(var.vt == VT_I2 || var.vt == VT_UI2 || var.vt == VT_I4 || var.vt == VT_UI4 || FAILED(hRes));
  268.         nAppearance = var.iVal;
  269.         return hRes;
  270.     }
  271.     HRESULT GetAmbientBackColor(OLE_COLOR& BackColor)
  272.     {
  273.         CComVariant var;
  274.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_BACKCOLOR, var);
  275.         ATLASSERT(var.vt == VT_I4 || var.vt == VT_UI4 || FAILED(hRes));
  276.         BackColor = var.lVal;
  277.         return hRes;
  278.     }
  279.     HRESULT GetAmbientDisplayName(BSTR& bstrDisplayName)
  280.     {
  281.         CComVariant var;
  282.         if (bstrDisplayName)
  283.         {
  284.             SysFreeString(bstrDisplayName);
  285.             bstrDisplayName = NULL;
  286.         }
  287.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_DISPLAYNAME, var);
  288.         if (SUCCEEDED(hRes))
  289.         {
  290.             if (var.vt != VT_BSTR)
  291.                 return E_FAIL;
  292.             bstrDisplayName = var.bstrVal;
  293.             var.vt = VT_EMPTY;
  294.             var.bstrVal = NULL;
  295.         }
  296.         return hRes;
  297.     }
  298.     HRESULT GetAmbientFont(IFont** ppFont)
  299.     {
  300.         // caller MUST Release the font!
  301.         if (ppFont == NULL)
  302.             return E_POINTER;
  303.         *ppFont = NULL;
  304.         CComVariant var;
  305.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FONT, var);
  306.         ATLASSERT((var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH) || FAILED(hRes));
  307.         if (SUCCEEDED(hRes) && var.pdispVal)
  308.         {
  309.             if (var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH)
  310.                 hRes = var.pdispVal->QueryInterface(IID_IFont, (void**)ppFont);
  311.             else
  312.                 hRes = DISP_E_BADVARTYPE;
  313.         }
  314.         return hRes;
  315.     }
  316.     HRESULT GetAmbientFontDisp(IFontDisp** ppFont)
  317.     {
  318.         // caller MUST Release the font!
  319.         if (ppFont == NULL)
  320.             return E_POINTER;
  321.         *ppFont = NULL;
  322.         CComVariant var;
  323.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FONT, var);
  324.         ATLASSERT((var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH) || FAILED(hRes));
  325.         if (SUCCEEDED(hRes) && var.pdispVal)
  326.         {
  327.             if (var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH)
  328.                 hRes = var.pdispVal->QueryInterface(IID_IFontDisp, (void**)ppFont);
  329.             else
  330.                 hRes = DISP_E_BADVARTYPE;
  331.         }
  332.         return hRes;
  333.     }
  334.     HRESULT GetAmbientForeColor(OLE_COLOR& ForeColor)
  335.     {
  336.         CComVariant var;
  337.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FORECOLOR, var);
  338.         ATLASSERT(var.vt == VT_I4 || var.vt == VT_UI4 || FAILED(hRes));
  339.         ForeColor = var.lVal;
  340.         return hRes;
  341.     }
  342.     HRESULT GetAmbientLocaleID(LCID& lcid)
  343.     {
  344.         CComVariant var;
  345.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_LOCALEID, var);
  346.         ATLASSERT((var.vt == VT_UI4 || var.vt == VT_I4) || FAILED(hRes));
  347.         lcid = var.lVal;
  348.         return hRes;
  349.     }
  350.     HRESULT GetAmbientScaleUnits(BSTR& bstrScaleUnits)
  351.     {
  352.         CComVariant var;
  353.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SCALEUNITS, var);
  354.         ATLASSERT(var.vt == VT_BSTR || FAILED(hRes));
  355.         bstrScaleUnits = var.bstrVal;
  356.         return hRes;
  357.     }
  358.     HRESULT GetAmbientTextAlign(short& nTextAlign)
  359.     {
  360.         CComVariant var;
  361.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_TEXTALIGN, var);
  362.         ATLASSERT(var.vt == VT_I2 || FAILED(hRes));
  363.         nTextAlign = var.iVal;
  364.         return hRes;
  365.     }
  366.     HRESULT GetAmbientUserMode(BOOL& bUserMode)
  367.     {
  368.         CComVariant var;
  369.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_USERMODE, var);
  370.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  371.         bUserMode = var.boolVal;
  372.         return hRes;
  373.     }
  374.     HRESULT GetAmbientUIDead(BOOL& bUIDead)
  375.     {
  376.         CComVariant var;
  377.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_UIDEAD, var);
  378.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  379.         bUIDead = var.boolVal;
  380.         return hRes;
  381.     }
  382.     HRESULT GetAmbientShowGrabHandles(BOOL& bShowGrabHandles)
  383.     {
  384.         CComVariant var;
  385.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SHOWGRABHANDLES, var);
  386.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  387.         bShowGrabHandles = var.boolVal;
  388.         return hRes;
  389.     }
  390.     HRESULT GetAmbientShowHatching(BOOL& bShowHatching)
  391.     {
  392.         CComVariant var;
  393.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SHOWHATCHING, var);
  394.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  395.         bShowHatching = var.boolVal;
  396.         return hRes;
  397.     }
  398.     HRESULT GetAmbientMessageReflect(BOOL& bMessageReflect)
  399.     {
  400.         CComVariant var;
  401.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_MESSAGEREFLECT, var);
  402.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  403.         bMessageReflect = var.boolVal;
  404.         return hRes;
  405.     }
  406.     HRESULT GetAmbientAutoClip(BOOL& bAutoClip)
  407.     {
  408.         CComVariant var;
  409.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_AUTOCLIP, var);
  410.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  411.         bAutoClip = var.boolVal;
  412.         return hRes;
  413.     }
  414.     HRESULT GetAmbientDisplayAsDefault(BOOL& bDisplaysDefault)
  415.     {
  416.         CComVariant var;
  417.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_DISPLAYASDEFAULT, var);
  418.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  419.         bDisplaysDefault = var.boolVal;
  420.         return hRes;
  421.     }
  422.     HRESULT GetAmbientSupportsMnemonics(BOOL& bSupportMnemonics)
  423.     {
  424.         CComVariant var;
  425.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SUPPORTSMNEMONICS, var);
  426.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  427.         bSupportMnemonics = var.boolVal;
  428.         return hRes;
  429.     }
  430.     HRESULT GetAmbientPalette(HPALETTE& hPalette)
  431.     {
  432.         CComVariant var;
  433.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_PALETTE, var);
  434.         ATLASSERT(var.vt == VT_I4 || var.vt == VT_UI4 || FAILED(hRes));
  435.         hPalette = reinterpret_cast<HPALETTE>(var.lVal);
  436.         return hRes;
  437.     }
  438.  
  439.     HRESULT InternalGetSite(REFIID riid, void** ppUnkSite)
  440.     {
  441.         ATLASSERT(ppUnkSite != NULL);
  442.         if (ppUnkSite == NULL)
  443.             return E_POINTER;
  444.         if (m_spClientSite == NULL)
  445.         {
  446.             *ppUnkSite = NULL;
  447.             return S_OK;
  448.         }
  449.         return m_spClientSite->QueryInterface(riid, ppUnkSite);
  450.     }
  451.  
  452.     BOOL DoesVerbUIActivate(LONG iVerb)
  453.     {
  454.         BOOL b = FALSE;
  455.         switch (iVerb)
  456.         {
  457.             case OLEIVERB_UIACTIVATE:
  458.             case OLEIVERB_PRIMARY:
  459.                 b = TRUE;
  460.                 break;
  461.         }
  462.         // if no ambient dispatch then in old style OLE container
  463.         if (DoesVerbActivate(iVerb) && m_spAmbientDispatch.p == NULL)
  464.             b = TRUE;
  465.         return b;
  466.     }
  467.  
  468.     BOOL DoesVerbActivate(LONG iVerb)
  469.     {
  470.         BOOL b = FALSE;
  471.         switch (iVerb)
  472.         {
  473.             case OLEIVERB_UIACTIVATE:
  474.             case OLEIVERB_PRIMARY:
  475.             case OLEIVERB_SHOW:
  476.             case OLEIVERB_INPLACEACTIVATE:
  477.                 b = TRUE;
  478.                 break;
  479.         }
  480.         return b;
  481.     }
  482.  
  483.     BOOL SetControlFocus(BOOL bGrab);
  484.     HRESULT IQuickActivate_QuickActivate(QACONTAINER *pQACont,
  485.         QACONTROL *pQACtrl);
  486.     HRESULT DoVerbProperties(LPCRECT /* prcPosRect */, HWND hwndParent);
  487.     HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect = NULL);
  488.  
  489.     HRESULT IOleObject_SetClientSite(IOleClientSite *pClientSite);
  490.     HRESULT IOleObject_GetClientSite(IOleClientSite **ppClientSite);
  491.     HRESULT IOleObject_Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection);
  492.     HRESULT IOleObject_Close(DWORD dwSaveOption);
  493.     HRESULT IOleObject_SetExtent(DWORD dwDrawAspect, SIZEL *psizel);
  494.     HRESULT IOleInPlaceObject_InPlaceDeactivate(void);
  495.     HRESULT IOleInPlaceObject_UIDeactivate(void);
  496.     HRESULT IOleInPlaceObject_SetObjectRects(LPCRECT prcPos,LPCRECT prcClip);
  497.     HRESULT IViewObject_Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect,
  498.         DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw,
  499.         LPCRECTL prcBounds, LPCRECTL prcWBounds);
  500.     HRESULT IDataObject_GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
  501.  
  502.     HRESULT FireViewChange();
  503.     LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& lResult);
  504.  
  505.     virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos) = 0;
  506.     virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv) = 0;
  507.     virtual HRESULT OnDrawAdvanced(ATL_DRAWINFO& di);
  508.     virtual HRESULT OnDraw(ATL_DRAWINFO& /*di*/)
  509.     {
  510.         return S_OK;
  511.     }
  512.  
  513.  
  514. // Attributes
  515. public:
  516.     CComPtr<IOleInPlaceSiteWindowless> m_spInPlaceSite;
  517.     CComPtr<IDataAdviseHolder> m_spDataAdviseHolder;
  518.     CComPtr<IOleAdviseHolder> m_spOleAdviseHolder;
  519.     CComPtr<IOleClientSite> m_spClientSite;
  520.     CComPtr<IAdviseSink> m_spAdviseSink;
  521.     CComDispatchDriver m_spAmbientDispatch;
  522.  
  523.     SIZE m_sizeNatural; //unscaled size in himetric
  524.     SIZE m_sizeExtent;  //current extents in himetric
  525.     RECT m_rcPos; // position in pixels
  526. #pragma warning(disable: 4510 4610) // unnamed union
  527.     union
  528.     {
  529.         HWND& m_hWndCD;
  530.         HWND* m_phWndCD;
  531.     };
  532. #pragma warning(default: 4510 4610)
  533.     union
  534.     {
  535.         // m_nFreezeEvents is the only one actually used
  536.         int m_nFreezeEvents; // count of freezes versus thaws
  537.  
  538.         // These are here to make stock properties work
  539.         IPictureDisp* m_pMouseIcon;
  540.         IPictureDisp* m_pPicture;
  541.         IFontDisp* m_pFont;
  542.         OLE_COLOR m_clrBackColor;
  543.         OLE_COLOR m_clrBorderColor;
  544.         OLE_COLOR m_clrFillColor;
  545.         OLE_COLOR m_clrForeColor;
  546.         BSTR m_bstrText;
  547.         BSTR m_bstrCaption;
  548.         BOOL m_bValid;
  549.         BOOL m_bTabStop;
  550.         BOOL m_bBorderVisible;
  551.         BOOL m_bEnabled;
  552.         LONG m_nBackStyle;
  553.         LONG m_nBorderStyle;
  554.         LONG m_nBorderWidth;
  555.         LONG m_nDrawMode;
  556.         LONG m_nDrawStyle;
  557.         LONG m_nDrawWidth;
  558.         LONG m_nFillStyle;
  559.         SHORT m_nAppearance;
  560.         LONG m_nMousePointer;
  561.         LONG m_nReadyState;
  562.     };
  563.  
  564.     unsigned m_bNegotiatedWnd:1;
  565.     unsigned m_bWndLess:1;
  566.     unsigned m_bInPlaceActive:1;
  567.     unsigned m_bUIActive:1;
  568.     unsigned m_bUsingWindowRgn:1;
  569.     unsigned m_bInPlaceSiteEx:1;
  570.     unsigned m_bWindowOnly:1;
  571.     unsigned m_bRequiresSave:1;
  572.     unsigned m_bWasOnceWindowless:1;
  573.     unsigned m_bAutoSize:1; //SetExtent fails if size doesn't match existing
  574.     unsigned m_bRecomposeOnResize:1; //implies OLEMISC_RECOMPOSEONRESIZE
  575.     unsigned m_bResizeNatural:1;  //resize natural extent on SetExtent
  576.     unsigned m_bDrawFromNatural:1; //instead of m_sizeExtent
  577.     unsigned m_bDrawGetDataInHimetric:1; //instead of pixels
  578.  
  579.     DECLARE_VIEW_STATUS(VIEWSTATUS_OPAQUE)
  580. };
  581.  
  582. inline HRESULT CComControlBase::IQuickActivate_QuickActivate(QACONTAINER *pQACont,
  583.     QACONTROL *pQACtrl)
  584. {
  585.     ATLASSERT(pQACont != NULL);
  586.     ATLASSERT(pQACtrl != NULL);
  587.     if (!pQACont || !pQACtrl)
  588.         return E_POINTER;
  589.  
  590.     HRESULT hRes;
  591.     ULONG uCB = pQACtrl->cbSize;
  592.     memset(pQACtrl, 0, uCB);
  593.     pQACtrl->cbSize = uCB;
  594.  
  595.     // get all interfaces we are going to need
  596.     CComPtr<IOleObject> pOO;
  597.     ControlQueryInterface(IID_IOleObject, (void**)&pOO);
  598.     CComPtr<IViewObjectEx> pVOEX;
  599.     ControlQueryInterface(IID_IViewObjectEx, (void**)&pVOEX);
  600.     CComPtr<IPointerInactive> pPI;
  601.     ControlQueryInterface(IID_IPointerInactive, (void**)&pPI);
  602.     CComPtr<IProvideClassInfo2> pPCI;
  603.     ControlQueryInterface(IID_IProvideClassInfo2, (void**)&pPCI);
  604.  
  605.     if (pOO == NULL || pVOEX == NULL)
  606.         return E_FAIL;
  607.  
  608.     pOO->SetClientSite(pQACont->pClientSite);
  609.  
  610.     if (pQACont->pAdviseSink != NULL)
  611.     {
  612.         ATLTRACE2(atlTraceControls,2,_T("Setting up IOleObject Advise\n"));
  613.         pVOEX->SetAdvise(DVASPECT_CONTENT, 0, pQACont->pAdviseSink);
  614.     }
  615.  
  616.     CComPtr<IConnectionPointContainer> pCPC;
  617.     ControlQueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  618.  
  619.     if (pQACont->pPropertyNotifySink)
  620.     {
  621.         ATLTRACE2(atlTraceControls,2,_T("Setting up PropNotify CP\n"));
  622.         CComPtr<IConnectionPoint> pCP;
  623.         if (pCPC != NULL)
  624.         {
  625.             hRes = pCPC->FindConnectionPoint(IID_IPropertyNotifySink, &pCP);
  626.             if (SUCCEEDED(hRes))
  627.                 pCP->Advise(pQACont->pPropertyNotifySink, &pQACtrl->dwPropNotifyCookie);
  628.         }
  629.     }
  630.  
  631.     if (pPCI)
  632.     {
  633.         GUID iidDefaultSrc;
  634.         if (SUCCEEDED(pPCI->GetGUID(GUIDKIND_DEFAULT_SOURCE_DISP_IID,
  635.             &iidDefaultSrc)))
  636.         {
  637.             if (pQACont->pUnkEventSink)
  638.             {
  639.                 ATLTRACE2(atlTraceControls,2,_T("Setting up Default Out Going Interface\n"));
  640.                 CComPtr<IConnectionPoint> pCP;
  641.                 if (pCPC != NULL)
  642.                 {
  643.                     hRes = pCPC->FindConnectionPoint(iidDefaultSrc, &pCP);
  644.                     if (SUCCEEDED(hRes))
  645.                         pCP->Advise(pQACont->pUnkEventSink, &pQACtrl->dwEventCookie);
  646.                 }
  647.             }
  648.         }
  649.     }
  650.     // give information to container
  651.     if (pOO != NULL)
  652.         pOO->GetMiscStatus(DVASPECT_CONTENT, &pQACtrl->dwMiscStatus);
  653.  
  654.     if (pVOEX != NULL)
  655.         pVOEX->GetViewStatus(&pQACtrl->dwViewStatus);
  656.  
  657.     if (pPI != NULL)
  658.         pPI->GetActivationPolicy(&pQACtrl->dwPointerActivationPolicy);
  659.     return S_OK;
  660. }
  661.  
  662. inline BOOL CComControlBase::SetControlFocus(BOOL bGrab)
  663. {
  664.     if (m_bWndLess)
  665.     {
  666.         if (!m_bUIActive && bGrab)
  667.             if (FAILED(InPlaceActivate(OLEIVERB_UIACTIVATE)))
  668.                 return FALSE;
  669.  
  670.         return (m_spInPlaceSite->SetFocus(bGrab) == S_OK);
  671.     }
  672.     else
  673.     {
  674.         // we've got a window.
  675.         //
  676.         if (m_bInPlaceActive)
  677.         {
  678.             HWND hwnd = (bGrab) ? m_hWndCD : ::GetParent(m_hWndCD);
  679.             if (!m_bUIActive && bGrab)
  680.                 return SUCCEEDED(InPlaceActivate(OLEIVERB_UIACTIVATE));
  681.             else
  682.             {
  683.                 if (!::IsChild(hwnd, ::GetFocus()))
  684.                     ::SetFocus(hwnd);
  685.                 return TRUE;
  686.             }
  687.         }
  688.     }
  689.     return FALSE;
  690. }
  691.  
  692. inline HRESULT CComControlBase::DoVerbProperties(LPCRECT /* prcPosRect */, HWND hwndParent)
  693. {
  694.     HRESULT hr = S_OK;
  695.     CComQIPtr <ISpecifyPropertyPages, &IID_ISpecifyPropertyPages> spPages;
  696.     CComQIPtr <IOleObject, &IID_IOleObject> spObj;
  697.     CComQIPtr <IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  698.  
  699.     if (spSite)
  700.     {
  701.         hr = spSite->ShowPropertyFrame();
  702.         if (SUCCEEDED(hr))
  703.             return hr;
  704.     }
  705.  
  706.     CComPtr<IUnknown> pUnk;
  707.     ControlQueryInterface(IID_IUnknown, (void**)&pUnk);
  708.     ATLASSERT(pUnk != NULL);
  709.     CAUUID pages;
  710.     spPages = pUnk;
  711.     if (spPages)
  712.     {
  713.         hr = spPages->GetPages(&pages);
  714.         if (SUCCEEDED(hr))
  715.         {
  716.             spObj = pUnk;
  717.             if (spObj)
  718.             {
  719.                 LPOLESTR szTitle = NULL;
  720.  
  721.                 spObj->GetUserType(USERCLASSTYPE_SHORT, &szTitle);
  722.  
  723.                 LCID lcid;
  724.                 if (FAILED(GetAmbientLocaleID(lcid)))
  725.                     lcid = LOCALE_USER_DEFAULT;
  726.  
  727.                 hr = OleCreatePropertyFrame(hwndParent, m_rcPos.top, m_rcPos.left, szTitle,
  728.                     1, &pUnk.p, pages.cElems, pages.pElems, lcid, 0, 0);
  729.  
  730.                 CoTaskMemFree(szTitle);
  731.             }
  732.             else
  733.             {
  734.                 hr = OLEOBJ_S_CANNOT_DOVERB_NOW;
  735.             }
  736.             CoTaskMemFree(pages.pElems);
  737.         }
  738.     }
  739.     else
  740.     {
  741.         hr = OLEOBJ_S_CANNOT_DOVERB_NOW;
  742.     }
  743.  
  744.     return hr;
  745. }
  746.  
  747. inline HRESULT CComControlBase::InPlaceActivate(LONG iVerb, const RECT* /*prcPosRect*/)
  748. {
  749.     HRESULT hr;
  750.  
  751.     if (m_spClientSite == NULL)
  752.         return S_OK;
  753.  
  754.     CComPtr<IOleInPlaceObject> pIPO;
  755.     ControlQueryInterface(IID_IOleInPlaceObject, (void**)&pIPO);
  756.     ATLASSERT(pIPO != NULL);
  757.  
  758.     if (!m_bNegotiatedWnd)
  759.     {
  760.         if (!m_bWindowOnly)
  761.             // Try for windowless site
  762.             hr = m_spClientSite->QueryInterface(IID_IOleInPlaceSiteWindowless, (void **)&m_spInPlaceSite);
  763.  
  764.         if (m_spInPlaceSite)
  765.         {
  766.             m_bInPlaceSiteEx = TRUE;
  767.             // CanWindowlessActivate returns S_OK or S_FALSE
  768.             if ( m_spInPlaceSite->CanWindowlessActivate() == S_OK )
  769.             {
  770.                 m_bWndLess = TRUE;
  771.                 m_bWasOnceWindowless = TRUE;
  772.             }
  773.             else
  774.             {
  775.                 m_bWndLess = FALSE;
  776.             }
  777.         }
  778.         else
  779.         {
  780.             m_spClientSite->QueryInterface(IID_IOleInPlaceSiteEx, (void **)&m_spInPlaceSite);
  781.             if (m_spInPlaceSite)
  782.                 m_bInPlaceSiteEx = TRUE;
  783.             else
  784.                 hr = m_spClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_spInPlaceSite);
  785.         }
  786.     }
  787.  
  788.     ATLASSERT(m_spInPlaceSite);
  789.     if (!m_spInPlaceSite)
  790.         return E_FAIL;
  791.  
  792.     m_bNegotiatedWnd = TRUE;
  793.  
  794.     if (!m_bInPlaceActive)
  795.     {
  796.  
  797.         BOOL bNoRedraw = FALSE;
  798.         if (m_bWndLess)
  799.             m_spInPlaceSite->OnInPlaceActivateEx(&bNoRedraw, ACTIVATE_WINDOWLESS);
  800.         else
  801.         {
  802.             if (m_bInPlaceSiteEx)
  803.                 m_spInPlaceSite->OnInPlaceActivateEx(&bNoRedraw, 0);
  804.             else
  805.             {
  806.                 hr = m_spInPlaceSite->CanInPlaceActivate();
  807.                 // CanInPlaceActivate returns S_FALSE or S_OK
  808.                 if (FAILED(hr))
  809.                     return hr;
  810.                 if ( hr != S_OK )
  811.                 {
  812.                    // CanInPlaceActivate returned S_FALSE.
  813.                    return( E_FAIL );
  814.                 }
  815.                 m_spInPlaceSite->OnInPlaceActivate();
  816.             }
  817.         }
  818.     }
  819.  
  820.     m_bInPlaceActive = TRUE;
  821.  
  822.     // get location in the parent window,
  823.     // as well as some information about the parent
  824.     //
  825.     OLEINPLACEFRAMEINFO frameInfo;
  826.     RECT rcPos, rcClip;
  827.     CComPtr<IOleInPlaceFrame> spInPlaceFrame;
  828.     CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow;
  829.     frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  830.     HWND hwndParent;
  831.     if (m_spInPlaceSite->GetWindow(&hwndParent) == S_OK)
  832.     {
  833.         m_spInPlaceSite->GetWindowContext(&spInPlaceFrame,
  834.             &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
  835.  
  836.         if (!m_bWndLess)
  837.         {
  838.             if (m_hWndCD)
  839.             {
  840.                 ShowWindow(m_hWndCD, SW_SHOW);
  841.                 if (!::IsChild(m_hWndCD, ::GetFocus()))
  842.                     ::SetFocus(m_hWndCD);
  843.             }
  844.             else
  845.             {
  846.                 HWND h = CreateControlWindow(hwndParent, rcPos);
  847.                 ATLASSERT(h != NULL);    // will assert if creation failed
  848.                 ATLASSERT(h == m_hWndCD);
  849.                 h;    // avoid unused warning
  850.             }
  851.         }
  852.  
  853.         pIPO->SetObjectRects(&rcPos, &rcClip);
  854.     }
  855.  
  856.     CComPtr<IOleInPlaceActiveObject> spActiveObject;
  857.     ControlQueryInterface(IID_IOleInPlaceActiveObject, (void**)&spActiveObject);
  858.  
  859.     // Gone active by now, take care of UIACTIVATE
  860.     if (DoesVerbUIActivate(iVerb))
  861.     {
  862.         if (!m_bUIActive)
  863.         {
  864.             m_bUIActive = TRUE;
  865.             hr = m_spInPlaceSite->OnUIActivate();
  866.             if (FAILED(hr))
  867.                 return hr;
  868.  
  869.             SetControlFocus(TRUE);
  870.             // set ourselves up in the host.
  871.             //
  872.             if (spActiveObject)
  873.             {
  874.                 if (spInPlaceFrame)
  875.                     spInPlaceFrame->SetActiveObject(spActiveObject, NULL);
  876.                 if (spInPlaceUIWindow)
  877.                     spInPlaceUIWindow->SetActiveObject(spActiveObject, NULL);
  878.             }
  879.  
  880.             if (spInPlaceFrame)
  881.                 spInPlaceFrame->SetBorderSpace(NULL);
  882.             if (spInPlaceUIWindow)
  883.                 spInPlaceUIWindow->SetBorderSpace(NULL);
  884.         }
  885.     }
  886.  
  887.     m_spClientSite->ShowObject();
  888.  
  889.     return S_OK;
  890. }
  891.  
  892. inline HRESULT CComControlBase::SendOnDataChange(DWORD advf)
  893. {
  894.     HRESULT hRes = S_OK;
  895.     if (m_spDataAdviseHolder)
  896.     {
  897.         CComPtr<IDataObject> pdo;
  898.         if (SUCCEEDED(ControlQueryInterface(IID_IDataObject, (void**)&pdo)))
  899.             hRes = m_spDataAdviseHolder->SendOnDataChange(pdo, 0, advf);
  900.     }
  901.     return hRes;
  902. }
  903.  
  904. inline HRESULT CComControlBase::IOleObject_SetClientSite(IOleClientSite *pClientSite)
  905. {
  906.     ATLASSERT(pClientSite == NULL || m_spClientSite == NULL);
  907.     m_spClientSite = pClientSite;
  908.     m_spAmbientDispatch.Release();
  909.     if (m_spClientSite != NULL)
  910.     {
  911.         m_spClientSite->QueryInterface(IID_IDispatch,
  912.             (void**) &m_spAmbientDispatch.p);
  913.     }
  914.     return S_OK;
  915. }
  916.  
  917. inline HRESULT CComControlBase::IOleObject_GetClientSite(IOleClientSite **ppClientSite)
  918. {
  919.     ATLASSERT(ppClientSite);
  920.     if (ppClientSite == NULL)
  921.         return E_POINTER;
  922.  
  923.     *ppClientSite = m_spClientSite;
  924.     if (m_spClientSite != NULL)
  925.         m_spClientSite.p->AddRef();
  926.     return S_OK;
  927. }
  928.  
  929. inline HRESULT CComControlBase::IOleObject_Advise(IAdviseSink *pAdvSink,
  930.     DWORD *pdwConnection)
  931. {
  932.     HRESULT hr = S_OK;
  933.     if (m_spOleAdviseHolder == NULL)
  934.         hr = CreateOleAdviseHolder(&m_spOleAdviseHolder);
  935.     if (SUCCEEDED(hr))
  936.         hr = m_spOleAdviseHolder->Advise(pAdvSink, pdwConnection);
  937.     return hr;
  938. }
  939.  
  940. inline HRESULT CComControlBase::IOleObject_Close(DWORD dwSaveOption)
  941. {
  942.     CComPtr<IOleInPlaceObject> pIPO;
  943.     ControlQueryInterface(IID_IOleInPlaceObject, (void**)&pIPO);
  944.     ATLASSERT(pIPO != NULL);
  945.     if (m_hWndCD)
  946.     {
  947.         if (m_spClientSite)
  948.             m_spClientSite->OnShowWindow(FALSE);
  949.     }
  950.  
  951.     if (m_bInPlaceActive)
  952.     {
  953.         HRESULT hr = pIPO->InPlaceDeactivate();
  954.         if (FAILED(hr))
  955.             return hr;
  956.         ATLASSERT(!m_bInPlaceActive);
  957.     }
  958.     if (m_hWndCD)
  959.     {
  960.         ATLTRACE2(atlTraceControls,2,_T("Destroying Window\n"));
  961.         if (::IsWindow(m_hWndCD))
  962.             DestroyWindow(m_hWndCD);
  963.         m_hWndCD = NULL;
  964.     }
  965.  
  966.     // handle the save flag.
  967.     //
  968.     if ((dwSaveOption == OLECLOSE_SAVEIFDIRTY ||
  969.         dwSaveOption == OLECLOSE_PROMPTSAVE) && m_bRequiresSave)
  970.     {
  971.         if (m_spClientSite)
  972.             m_spClientSite->SaveObject();
  973.         SendOnSave();
  974.     }
  975.  
  976.     m_spInPlaceSite.Release();
  977.     m_bNegotiatedWnd = FALSE;
  978.     m_bWndLess = FALSE;
  979.     m_bInPlaceSiteEx = FALSE;
  980.     m_spAdviseSink.Release();
  981.     return S_OK;
  982. }
  983.  
  984. inline HRESULT CComControlBase::IOleInPlaceObject_InPlaceDeactivate(void)
  985. {
  986.     CComPtr<IOleInPlaceObject> pIPO;
  987.     ControlQueryInterface(IID_IOleInPlaceObject, (void**)&pIPO);
  988.     ATLASSERT(pIPO != NULL);
  989.  
  990.     if (!m_bInPlaceActive)
  991.         return S_OK;
  992.     pIPO->UIDeactivate();
  993.  
  994.     m_bInPlaceActive = FALSE;
  995.  
  996.     // if we have a window, tell it to go away.
  997.     //
  998.     if (m_hWndCD)
  999.     {
  1000.         ATLTRACE2(atlTraceControls,2,_T("Destroying Window\n"));
  1001.         if (::IsWindow(m_hWndCD))
  1002.             DestroyWindow(m_hWndCD);
  1003.         m_hWndCD = NULL;
  1004.     }
  1005.  
  1006.     if (m_spInPlaceSite)
  1007.         m_spInPlaceSite->OnInPlaceDeactivate();
  1008.  
  1009.     return S_OK;
  1010. }
  1011.  
  1012. inline HRESULT CComControlBase::IOleInPlaceObject_UIDeactivate(void)
  1013. {
  1014.     // if we're not UIActive, not much to do.
  1015.     //
  1016.     if (!m_bUIActive)
  1017.         return S_OK;
  1018.  
  1019.     m_bUIActive = FALSE;
  1020.  
  1021.     // notify frame windows, if appropriate, that we're no longer ui-active.
  1022.     //
  1023.     CComPtr<IOleInPlaceFrame> spInPlaceFrame;
  1024.     CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow;
  1025.     OLEINPLACEFRAMEINFO frameInfo;
  1026.     frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  1027.     RECT rcPos, rcClip;
  1028.  
  1029.     HWND hwndParent; 
  1030.     // This call to GetWindow is a fix for Delphi
  1031.     if (m_spInPlaceSite->GetWindow(&hwndParent) == S_OK)
  1032.     {
  1033.         m_spInPlaceSite->GetWindowContext(&spInPlaceFrame,
  1034.             &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
  1035.         if (spInPlaceUIWindow)
  1036.             spInPlaceUIWindow->SetActiveObject(NULL, NULL);
  1037.         if (spInPlaceFrame)
  1038.             spInPlaceFrame->SetActiveObject(NULL, NULL);
  1039.     }
  1040.     // we don't need to explicitly release the focus here since somebody
  1041.     // else grabbing the focus is what is likely to cause us to get lose it
  1042.     //
  1043.     m_spInPlaceSite->OnUIDeactivate(FALSE);
  1044.  
  1045.     return S_OK;
  1046. }
  1047.  
  1048. inline HRESULT CComControlBase::IOleInPlaceObject_SetObjectRects(LPCRECT prcPos,LPCRECT prcClip)
  1049. {
  1050.     if (prcPos == NULL || prcClip == NULL)
  1051.         return E_POINTER;
  1052.  
  1053.     m_rcPos = *prcPos;
  1054.     if (m_hWndCD)
  1055.     {
  1056.         // the container wants us to clip, so figure out if we really
  1057.         // need to
  1058.         //
  1059.         RECT rcIXect;
  1060.         BOOL b = IntersectRect(&rcIXect, prcPos, prcClip);
  1061.         HRGN tempRgn = NULL;
  1062.         if (b && !EqualRect(&rcIXect, prcPos))
  1063.         {
  1064.             OffsetRect(&rcIXect, -(prcPos->left), -(prcPos->top));
  1065.             tempRgn = CreateRectRgnIndirect(&rcIXect);
  1066.         }
  1067.  
  1068.         SetWindowRgn(m_hWndCD, tempRgn, TRUE);
  1069.  
  1070.         // set our control's location, but don't change it's size at all
  1071.         // [people for whom zooming is important should set that up here]
  1072.         //
  1073.         SIZEL size = {prcPos->right - prcPos->left, prcPos->bottom - prcPos->top};
  1074.         SetWindowPos(m_hWndCD, NULL, prcPos->left,
  1075.                      prcPos->top, size.cx, size.cy, SWP_NOZORDER | SWP_NOACTIVATE);
  1076.     }
  1077.  
  1078.     return S_OK;
  1079. }
  1080.  
  1081. inline HRESULT CComControlBase::IOleObject_SetExtent(DWORD dwDrawAspect, SIZEL *psizel)
  1082. {
  1083.     if (dwDrawAspect != DVASPECT_CONTENT)
  1084.         return DV_E_DVASPECT;
  1085.     if (psizel == NULL)
  1086.         return E_POINTER;
  1087.  
  1088.     BOOL bSizeMatchesNatural =
  1089.         memcmp(psizel, &m_sizeNatural, sizeof(SIZE)) == 0;
  1090.  
  1091.     if (m_bAutoSize) //object can't do any other size
  1092.         return (bSizeMatchesNatural) ? S_OK : E_FAIL;
  1093.  
  1094.     BOOL bResized = FALSE;
  1095.     if (memcmp(psizel, &m_sizeExtent, sizeof(SIZE)) != 0)
  1096.     {
  1097.         m_sizeExtent = *psizel;
  1098.         bResized = TRUE;
  1099.     }
  1100.     if (m_bResizeNatural && !bSizeMatchesNatural)
  1101.     {
  1102.         m_sizeNatural = *psizel;
  1103.         bResized = TRUE;
  1104.     }
  1105.  
  1106.     if (m_bRecomposeOnResize && bResized)
  1107.     {
  1108.         SendOnDataChange();
  1109.         FireViewChange();
  1110.     }
  1111.     return S_OK;
  1112. }
  1113.  
  1114. inline HRESULT CComControlBase::IViewObject_Draw(DWORD dwDrawAspect, LONG lindex,
  1115.     void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw,
  1116.     LPCRECTL prcBounds, LPCRECTL prcWBounds)
  1117. {
  1118.     ATLTRACE2(atlTraceControls,2,_T("Draw dwDrawAspect=%x lindex=%d ptd=%x hic=%x hdc=%x\n"),
  1119.         dwDrawAspect, lindex, ptd, hicTargetDev, hdcDraw);
  1120. #ifdef _DEBUG
  1121.     if (prcBounds == NULL)
  1122.         ATLTRACE2(atlTraceControls,2,_T("\tprcBounds=NULL\n"));
  1123.     else
  1124.         ATLTRACE2(atlTraceControls,2,_T("\tprcBounds=%d,%d,%d,%d\n"), prcBounds->left,
  1125.             prcBounds->top, prcBounds->right, prcBounds->bottom);
  1126.     if (prcWBounds == NULL)
  1127.         ATLTRACE2(atlTraceControls,2,_T("\tprcWBounds=NULL\n"));
  1128.     else
  1129.         ATLTRACE2(atlTraceControls,2,_T("\tprcWBounds=%d,%d,%d,%d\n"), prcWBounds->left,
  1130.             prcWBounds->top, prcWBounds->right, prcWBounds->bottom);
  1131. #endif
  1132.  
  1133.     if (prcBounds == NULL)
  1134.     {
  1135.         if (!m_bWndLess)
  1136.             return E_INVALIDARG;
  1137.         prcBounds = (RECTL*)&m_rcPos;
  1138.     }
  1139.  
  1140.     // support the aspects required for multi-pass drawing
  1141.     switch (dwDrawAspect)
  1142.     {
  1143.         case DVASPECT_CONTENT:
  1144.         case DVASPECT_OPAQUE:
  1145.         case DVASPECT_TRANSPARENT:
  1146.             break;
  1147.         default:
  1148.             ATLASSERT(FALSE);
  1149.             return DV_E_DVASPECT;
  1150.             break;
  1151.     }
  1152.  
  1153.     // make sure nobody forgets to do this
  1154.     if (ptd == NULL)
  1155.         hicTargetDev = NULL;
  1156.  
  1157.     BOOL bOptimize = FALSE;
  1158.     if (pvAspect && ((DVASPECTINFO *)pvAspect)->cb >= sizeof(DVASPECTINFO))
  1159.         bOptimize = (((DVASPECTINFO *)pvAspect)->dwFlags & DVASPECTINFOFLAG_CANOPTIMIZE);
  1160.  
  1161.     ATL_DRAWINFO di;
  1162.     memset(&di, 0, sizeof(di));
  1163.     di.cbSize = sizeof(di);
  1164.     di.dwDrawAspect = dwDrawAspect;
  1165.     di.lindex = lindex;
  1166.     di.ptd = ptd;
  1167.     di.hicTargetDev = hicTargetDev;
  1168.     di.hdcDraw = hdcDraw;
  1169.     di.prcBounds = prcBounds;
  1170.     di.prcWBounds = prcWBounds;
  1171.     di.bOptimize = bOptimize;
  1172.     return OnDrawAdvanced(di);
  1173. }
  1174.  
  1175. inline HRESULT CComControlBase::IDataObject_GetData(FORMATETC *pformatetcIn,
  1176.     STGMEDIUM *pmedium)
  1177. {
  1178.     if (pmedium == NULL)
  1179.         return E_POINTER;
  1180.     memset(pmedium, 0, sizeof(STGMEDIUM));
  1181.     ATLTRACE2(atlTraceControls,2,_T("Format = %x\n"), pformatetcIn->cfFormat);
  1182.     ATLTRACE2(atlTraceControls,2,_T("TYMED = %x\n"), pformatetcIn->tymed);
  1183.  
  1184.     if ((pformatetcIn->tymed & TYMED_MFPICT) == 0)
  1185.         return DATA_E_FORMATETC;
  1186.  
  1187.     SIZEL sizeMetric, size;
  1188.     if (m_bDrawFromNatural)
  1189.         sizeMetric = m_sizeNatural;
  1190.     else
  1191.         sizeMetric = m_sizeExtent;
  1192.     if (!m_bDrawGetDataInHimetric)
  1193.         AtlHiMetricToPixel(&sizeMetric, &size);
  1194.     else
  1195.         size = sizeMetric;
  1196.     RECTL rectl = {0 ,0, size.cx, size.cy};
  1197.  
  1198.     ATL_DRAWINFO di;
  1199.     memset(&di, 0, sizeof(di));
  1200.     di.cbSize = sizeof(di);
  1201.     di.dwDrawAspect = DVASPECT_CONTENT;
  1202.     di.lindex = -1;
  1203.     di.ptd = NULL;
  1204.     di.hicTargetDev = NULL;
  1205.     di.prcBounds = &rectl;
  1206.     di.prcWBounds = &rectl;
  1207.     di.bOptimize = TRUE; //we do a SaveDC/RestoreDC
  1208.     di.bRectInHimetric = m_bDrawGetDataInHimetric;
  1209.     // create appropriate memory metafile DC
  1210.     di.hdcDraw = CreateMetaFile(NULL);
  1211.  
  1212.     // create attribute DC according to pformatetcIn->ptd
  1213.  
  1214.     SaveDC(di.hdcDraw);
  1215.     SetWindowOrgEx(di.hdcDraw, 0, 0, NULL);
  1216.     SetWindowExtEx(di.hdcDraw, rectl.right, rectl.bottom, NULL);
  1217.     OnDrawAdvanced(di);
  1218.     RestoreDC(di.hdcDraw, -1);
  1219.  
  1220.     HMETAFILE hMF = CloseMetaFile(di.hdcDraw);
  1221.     if (hMF == NULL)
  1222.         return E_UNEXPECTED;
  1223.  
  1224.     HGLOBAL hMem=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(METAFILEPICT));
  1225.  
  1226.     if (NULL==hMem)
  1227.     {
  1228.         DeleteMetaFile(hMF);
  1229.         return ResultFromScode(STG_E_MEDIUMFULL);
  1230.     }
  1231.  
  1232.     LPMETAFILEPICT pMF=(LPMETAFILEPICT)GlobalLock(hMem);
  1233.     pMF->hMF=hMF;
  1234.     pMF->mm=MM_ANISOTROPIC;
  1235.     pMF->xExt=sizeMetric.cx;
  1236.     pMF->yExt=sizeMetric.cy;
  1237.     GlobalUnlock(hMem);
  1238.  
  1239.     pmedium->tymed = TYMED_MFPICT;
  1240.     pmedium->hGlobal = hMem;
  1241.     pmedium->pUnkForRelease = NULL;
  1242.  
  1243.     return S_OK;
  1244. }
  1245.  
  1246. inline HRESULT CComControlBase::FireViewChange()
  1247. {
  1248.     if (m_bInPlaceActive)
  1249.     {
  1250.         // Active
  1251.         if (m_hWndCD != NULL)
  1252.             ::InvalidateRect(m_hWndCD, NULL, TRUE); // Window based
  1253.         else if (m_spInPlaceSite != NULL)
  1254.             m_spInPlaceSite->InvalidateRect(NULL, TRUE); // Windowless
  1255.     }
  1256.     else // Inactive
  1257.         SendOnViewChange(DVASPECT_CONTENT);
  1258.     return S_OK;
  1259. }
  1260.  
  1261. inline void CComControlBase::GetZoomInfo(ATL_DRAWINFO& di)
  1262. {
  1263.     const RECTL& rcPos = *di.prcBounds;
  1264.     SIZEL sizeDen;
  1265.     if (m_bDrawFromNatural)
  1266.         sizeDen = m_sizeNatural;
  1267.     else
  1268.         sizeDen = m_sizeExtent;
  1269.     if (!di.bRectInHimetric)
  1270.         AtlHiMetricToPixel(&sizeDen, &sizeDen);
  1271.     SIZEL sizeNum = {rcPos.right-rcPos.left, rcPos.bottom-rcPos.top};
  1272.     di.ZoomNum.cx = sizeNum.cx;
  1273.     di.ZoomNum.cy = sizeNum.cy;
  1274.     di.ZoomDen.cx = sizeDen.cx;
  1275.     di.ZoomDen.cy = sizeDen.cy;
  1276.     if (sizeDen.cx == 0 || sizeDen.cy == 0 ||
  1277.         sizeNum.cx == 0 || sizeNum.cy == 0)
  1278.     {
  1279.         di.ZoomNum.cx = di.ZoomNum.cy = di.ZoomDen.cx = di.ZoomDen.cy = 1;
  1280.         di.bZoomed = FALSE;
  1281.     }
  1282.     else if (sizeNum.cx != sizeDen.cx || sizeNum.cy != sizeDen.cy)
  1283.         di.bZoomed = TRUE;
  1284.     else
  1285.         di.bZoomed = FALSE;
  1286. }
  1287.  
  1288. inline HRESULT CComControlBase::OnDrawAdvanced(ATL_DRAWINFO& di)
  1289. {
  1290.     BOOL bDeleteDC = FALSE;
  1291.     if (di.hicTargetDev == NULL)
  1292.     {
  1293.         di.hicTargetDev = AtlCreateTargetDC(di.hdcDraw, di.ptd);
  1294.         bDeleteDC = (di.hicTargetDev != di.hdcDraw);
  1295.     }
  1296.     RECTL rectBoundsDP = *di.prcBounds;
  1297.     BOOL bMetafile = GetDeviceCaps(di.hdcDraw, TECHNOLOGY) == DT_METAFILE;
  1298.     if (!bMetafile)
  1299.     {
  1300.         ::LPtoDP(di.hicTargetDev, (LPPOINT)&rectBoundsDP, 2);
  1301.         SaveDC(di.hdcDraw);
  1302.         SetMapMode(di.hdcDraw, MM_TEXT);
  1303.         SetWindowOrgEx(di.hdcDraw, 0, 0, NULL);
  1304.         SetViewportOrgEx(di.hdcDraw, 0, 0, NULL);
  1305.         di.bOptimize = TRUE; //since we save the DC we can do this
  1306.     }
  1307.     di.prcBounds = &rectBoundsDP;
  1308.     GetZoomInfo(di);
  1309.  
  1310.     HRESULT hRes = OnDraw(di);
  1311.     if (bDeleteDC)
  1312.         ::DeleteDC(di.hicTargetDev);
  1313.     if (!bMetafile)
  1314.         RestoreDC(di.hdcDraw, -1);
  1315.     return hRes;
  1316. }
  1317.  
  1318. inline LRESULT CComControlBase::OnPaint(UINT /* uMsg */, WPARAM wParam,
  1319.     LPARAM /* lParam */, BOOL& /* lResult */)
  1320. {
  1321.     RECT rc;
  1322.     PAINTSTRUCT ps;
  1323.  
  1324.     HDC hdc = (wParam != NULL) ? (HDC)wParam : ::BeginPaint(m_hWndCD, &ps);
  1325.     if (hdc == NULL)
  1326.         return 0;
  1327.     ::GetClientRect(m_hWndCD, &rc);
  1328.  
  1329.     ATL_DRAWINFO di;
  1330.     memset(&di, 0, sizeof(di));
  1331.     di.cbSize = sizeof(di);
  1332.     di.dwDrawAspect = DVASPECT_CONTENT;
  1333.     di.lindex = -1;
  1334.     di.hdcDraw = hdc;
  1335.     di.prcBounds = (LPCRECTL)&rc;
  1336.  
  1337.     OnDrawAdvanced(di);
  1338.     if (wParam == NULL)
  1339.         ::EndPaint(m_hWndCD, &ps);
  1340.     return 0;
  1341. }
  1342.  
  1343. template <class T, class WinBase =  CWindowImpl< T > >
  1344. class ATL_NO_VTABLE CComControl :  public CComControlBase, public WinBase
  1345. {
  1346. public:
  1347.     CComControl() : CComControlBase(m_hWnd) {}
  1348.     HRESULT FireOnRequestEdit(DISPID dispID)
  1349.     {
  1350.         T* pT = static_cast<T*>(this);
  1351.         return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnRequestEdit(pT->GetUnknown(), dispID);
  1352.     }
  1353.     HRESULT FireOnChanged(DISPID dispID)
  1354.     {
  1355.         T* pT = static_cast<T*>(this);
  1356.         return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnChanged(pT->GetUnknown(), dispID);
  1357.     }
  1358.     virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv)
  1359.     {
  1360.         T* pT = static_cast<T*>(this);
  1361.         return pT->_InternalQueryInterface(iid, ppv);
  1362.     }
  1363.     virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos)
  1364.     {
  1365.         T* pT = static_cast<T*>(this);
  1366.         return pT->Create(hWndParent, rcPos);
  1367.     }
  1368.  
  1369.     typedef CComControl< T, WinBase >    thisClass;
  1370.     BEGIN_MSG_MAP(thisClass)
  1371.         MESSAGE_HANDLER(WM_PAINT, CComControlBase::OnPaint)
  1372.         MESSAGE_HANDLER(WM_SETFOCUS, CComControlBase::OnSetFocus)
  1373.         MESSAGE_HANDLER(WM_KILLFOCUS, CComControlBase::OnKillFocus)
  1374.         MESSAGE_HANDLER(WM_MOUSEACTIVATE, CComControlBase::OnMouseActivate)
  1375.     END_MSG_MAP()
  1376. };
  1377.  
  1378. //////////////////////////////////////////////////////////////////////////////
  1379. // CComCompositeControl
  1380.  
  1381. #ifndef _ATL_NO_HOSTING
  1382. template <class T>
  1383. class CComCompositeControl : public CComControl< T, CAxDialogImpl< T > >
  1384. {
  1385. public:
  1386.     CComCompositeControl()
  1387.     {
  1388.         m_hbrBackground = NULL;
  1389.     }
  1390.     ~CComCompositeControl()
  1391.     {
  1392.         DeleteObject(m_hbrBackground);
  1393.     }
  1394.     HRESULT AdviseSinkMap(bool bAdvise)
  1395.     {
  1396.         if(!bAdvise && m_hWnd == NULL)
  1397.         {
  1398.             // window is gone, controls are already unadvised
  1399.             ATLTRACE2(atlTraceControls, 1, _T("CComCompositeControl::AdviseSinkMap called after the window was destroyed\n"));
  1400.             return S_OK;
  1401.         }
  1402.         T* pT = static_cast<T*>(this);
  1403.         return AtlAdviseSinkMap(pT, bAdvise);
  1404.     }
  1405.     HBRUSH m_hbrBackground;
  1406.     HRESULT SetBackgroundColorFromAmbient()
  1407.     {
  1408.         if (m_hbrBackground != NULL)
  1409.         {
  1410.             DeleteObject(m_hbrBackground);
  1411.             m_hbrBackground = NULL;
  1412.         }
  1413.         OLE_COLOR clr;
  1414.         HRESULT hr = GetAmbientBackColor(clr);
  1415.         if (SUCCEEDED(hr))
  1416.         {
  1417.             COLORREF rgb;
  1418.             ::OleTranslateColor(clr, NULL, &rgb);
  1419.             m_hbrBackground = ::CreateSolidBrush(rgb);
  1420.             EnumChildWindows(m_hWnd, (WNDENUMPROC)BackgroundColorEnumProc, (LPARAM) clr);
  1421.         }
  1422.         return hr;
  1423.     }
  1424.     static BOOL CALLBACK BackgroundColorEnumProc(HWND hwnd, LPARAM l)
  1425.     {
  1426.         CAxWindow wnd(hwnd);
  1427.         CComPtr<IAxWinAmbientDispatch> spDispatch;
  1428.         wnd.QueryHost(&spDispatch);
  1429.         if (spDispatch != NULL)
  1430.             spDispatch->put_BackColor((OLE_COLOR)l);
  1431.         return TRUE;
  1432.     }
  1433.     LRESULT OnDialogColor(UINT, WPARAM w, LPARAM, BOOL&)
  1434.     {
  1435.         HDC dc = (HDC) w;
  1436.         LOGBRUSH lb;
  1437.         ::GetObject(m_hbrBackground, sizeof(lb), (void*)&lb);
  1438.         ::SetBkColor(dc, lb.lbColor);
  1439.         return (LRESULT)m_hbrBackground;
  1440.     }
  1441.     HWND Create(HWND hWndParent, RECT& /*rcPos*/, LPARAM dwInitParam = NULL)
  1442.     {
  1443.         CComControl< T, CAxDialogImpl< T > >::Create(hWndParent, dwInitParam);
  1444.         SetBackgroundColorFromAmbient();
  1445.         if (m_hWnd != NULL)
  1446.             ShowWindow(SW_SHOWNOACTIVATE);
  1447.         return m_hWnd;
  1448.     }
  1449.     BOOL CalcExtent(SIZE& size)
  1450.     {
  1451.         HINSTANCE hInstance = _Module.GetResourceInstance();
  1452.         LPCTSTR lpTemplateName = MAKEINTRESOURCE(T::IDD);
  1453.         HRSRC hDlgTempl = FindResource(hInstance, lpTemplateName, RT_DIALOG);
  1454.         if (hDlgTempl == NULL)
  1455.             return FALSE;
  1456.         HGLOBAL hResource = LoadResource(hInstance, hDlgTempl);
  1457.         DLGTEMPLATE* pDlgTempl = (DLGTEMPLATE*)LockResource(hResource);
  1458.         if (pDlgTempl == NULL)
  1459.             return FALSE;
  1460.         AtlGetDialogSize(pDlgTempl, &size);
  1461.         AtlPixelToHiMetric(&size, &size);
  1462.         return TRUE;
  1463.     }
  1464. //Implementation
  1465.     BOOL PreTranslateAccelerator(LPMSG pMsg, HRESULT& hRet)
  1466.     {
  1467.         hRet = S_OK;
  1468.         if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) &&
  1469.            (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST))
  1470.             return FALSE;
  1471.         // find a direct child of the dialog from the window that has focus
  1472.         HWND hWndCtl = ::GetFocus();
  1473.         if (IsChild(hWndCtl) && ::GetParent(hWndCtl) != m_hWnd)
  1474.         {
  1475.             do
  1476.             {
  1477.                 hWndCtl = ::GetParent(hWndCtl);
  1478.             }
  1479.             while (::GetParent(hWndCtl) != m_hWnd);
  1480.         }
  1481.         // give controls a chance to translate this message
  1482.         if (::SendMessage(hWndCtl, WM_FORWARDMSG, 0, (LPARAM)pMsg) == 1)
  1483.             return TRUE;
  1484.  
  1485.         // special handling for keyboard messages
  1486.         DWORD dwDlgCode = ::SendMessage(pMsg->hwnd, WM_GETDLGCODE, 0, 0L);
  1487.         switch(pMsg->message)
  1488.         {
  1489.         case WM_CHAR:
  1490.             if(dwDlgCode == 0)    // no dlgcode, possibly an ActiveX control
  1491.                 return FALSE;    // let the container process this
  1492.             break;
  1493.         case WM_KEYDOWN:
  1494.             switch(LOWORD(pMsg->wParam))
  1495.             {
  1496.             case VK_TAB:
  1497.                 // prevent tab from looping inside of our dialog
  1498.                 if((dwDlgCode & DLGC_WANTTAB) == 0)
  1499.                 {
  1500.                     HWND hWndFirstOrLast = ::GetWindow(m_hWnd, GW_CHILD);
  1501.                     if (::GetKeyState(VK_SHIFT) >= 0)  // not pressed
  1502.                         hWndFirstOrLast = GetNextDlgTabItem(hWndFirstOrLast, TRUE);
  1503.                     if (hWndFirstOrLast == hWndCtl)
  1504.                         return FALSE;
  1505.                 }
  1506.                 break;
  1507.             case VK_LEFT:
  1508.             case VK_UP:
  1509.             case VK_RIGHT:
  1510.             case VK_DOWN:
  1511.                 // prevent arrows from looping inside of our dialog
  1512.                 if((dwDlgCode & DLGC_WANTARROWS) == 0)
  1513.                 {
  1514.                     HWND hWndFirstOrLast = ::GetWindow(m_hWnd, GW_CHILD);
  1515.                     if (pMsg->wParam == VK_RIGHT || pMsg->wParam == VK_DOWN)    // going forward
  1516.                         hWndFirstOrLast = GetNextDlgTabItem(hWndFirstOrLast, TRUE);
  1517.                     if (hWndFirstOrLast == hWndCtl)
  1518.                         return FALSE;
  1519.                 }
  1520.                 break;
  1521.             case VK_EXECUTE:
  1522.             case VK_RETURN:
  1523.             case VK_ESCAPE:
  1524.             case VK_CANCEL:
  1525.                 // we don't want to handle these, let the container do it
  1526.                 return FALSE;
  1527.             }
  1528.             break;
  1529.         }
  1530.  
  1531.         return IsDialogMessage(pMsg);
  1532.     }
  1533.     HRESULT IOleInPlaceObject_InPlaceDeactivate(void)
  1534.     {
  1535.         AdviseSinkMap(false); //unadvise
  1536.         return CComControl<T, CAxDialogImpl<T> >::IOleInPlaceObject_InPlaceDeactivate();
  1537.     }
  1538.     virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos)
  1539.     {
  1540.         T* pT = static_cast<T*>(this);
  1541.         HWND h = pT->Create(hWndParent, rcPos);
  1542.         if (h != NULL)
  1543.             AdviseSinkMap(true);
  1544.         return h;
  1545.     }
  1546.     virtual HRESULT OnDraw(ATL_DRAWINFO& di)
  1547.     {
  1548.         if(!m_bInPlaceActive)
  1549.         {
  1550.             HPEN hPen = (HPEN)::GetStockObject(BLACK_PEN);
  1551.             HBRUSH hBrush = (HBRUSH)::GetStockObject(GRAY_BRUSH);
  1552.             ::SelectObject(di.hdcDraw, hPen);
  1553.             ::SelectObject(di.hdcDraw, hBrush);
  1554.             ::Rectangle(di.hdcDraw, di.prcBounds->left, di.prcBounds->top, di.prcBounds->right, di.prcBounds->bottom);
  1555.             ::SetTextColor(di.hdcDraw, ::GetSysColor(COLOR_WINDOWTEXT));
  1556.             ::SetBkMode(di.hdcDraw, TRANSPARENT);
  1557.             ::DrawText(di.hdcDraw, _T("ATL Composite Control"), -1, (LPRECT)di.prcBounds, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
  1558.         }
  1559.         return S_OK;
  1560.     }
  1561.     typedef CComControl< T, CAxDialogImpl< T > >    baseClass;
  1562.     BEGIN_MSG_MAP(CComCompositeControl< T >)
  1563.         MESSAGE_HANDLER(WM_CTLCOLORDLG, OnDialogColor)
  1564.         MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnDialogColor)
  1565.         MESSAGE_HANDLER(WM_SETFOCUS, baseClass::OnSetFocus)
  1566.         MESSAGE_HANDLER(WM_KILLFOCUS, baseClass::OnKillFocus)
  1567.         MESSAGE_HANDLER(WM_MOUSEACTIVATE, baseClass::OnMouseActivate)
  1568.     END_MSG_MAP()
  1569.  
  1570.     BEGIN_SINK_MAP(T)
  1571.     END_SINK_MAP()
  1572. };
  1573. #endif //_ATL_NO_HOSTING
  1574.  
  1575. // Forward declarations
  1576. //
  1577. template <class T> class IPersistStorageImpl;
  1578. template <class T> class IPersistPropertyBagImpl;
  1579.  
  1580. template <class T> class IOleControlImpl;
  1581. template <class T> class IRunnableObjectImpl;
  1582. template <class T> class IQuickActivateImpl;
  1583. template <class T> class IOleObjectImpl;
  1584. template <class T> class IPropertyPageImpl;
  1585. template <class T> class IPropertyPage2Impl;
  1586. template <class T> class IPerPropertyBrowsingImpl;
  1587. template <class T> class IViewObjectExImpl;
  1588. template <class T> class IOleWindowImpl;
  1589. template <class T> class IPointerInactiveImpl;
  1590. template <class T, class CDV> class IPropertyNotifySinkCP;
  1591. template <class T> class IBindStatusCallbackImpl;
  1592. template <class T> class CBindStatusCallback;
  1593.  
  1594.  
  1595. //////////////////////////////////////////////////////////////////////////////
  1596. // IOleControlImpl
  1597. template <class T>
  1598. class ATL_NO_VTABLE IOleControlImpl : public IOleControl
  1599. {
  1600. public:
  1601.     STDMETHOD(GetControlInfo)(LPCONTROLINFO /* pCI */)
  1602.     {
  1603.         ATLTRACENOTIMPL(_T("IOleControlImpl::GetControlInfo"));
  1604.     }
  1605.     STDMETHOD(OnMnemonic)(LPMSG /* pMsg */)
  1606.     {
  1607.         ATLTRACENOTIMPL(_T("IOleControlImpl::OnMnemonic"));
  1608.     }
  1609.     STDMETHOD(OnAmbientPropertyChange)(DISPID dispid)
  1610.     {
  1611.         dispid;
  1612.         ATLTRACE2(atlTraceControls,2,_T("IOleControlImpl::OnAmbientPropertyChange\n"));
  1613.         ATLTRACE2(atlTraceControls,2,_T(" -- DISPID = %d (%d)\n"), dispid);
  1614.         return S_OK;
  1615.     }
  1616.     STDMETHOD(FreezeEvents)(BOOL bFreeze)
  1617.     {
  1618.         T* pT = static_cast<T*>(this);
  1619.         ATLTRACE2(atlTraceControls,2,_T("IOleControlImpl::FreezeEvents\n"));
  1620.         if (bFreeze)
  1621.             pT->m_nFreezeEvents++;
  1622.         else
  1623.             pT->m_nFreezeEvents--;
  1624.         return S_OK;
  1625.     }
  1626. };
  1627.  
  1628.  
  1629. //////////////////////////////////////////////////////////////////////////////
  1630. // IQuickActivateImpl
  1631. template <class T>
  1632. class ATL_NO_VTABLE IQuickActivateImpl : public IQuickActivate
  1633. {
  1634. public:
  1635.     STDMETHOD(QuickActivate)(QACONTAINER *pQACont, QACONTROL *pQACtrl)
  1636.     {
  1637.         T* pT = static_cast<T*>(this);
  1638.         ATLTRACE2(atlTraceControls,2,_T("IQuickActivateImpl::QuickActivate\n"));
  1639.         return pT->IQuickActivate_QuickActivate(pQACont, pQACtrl);
  1640.     }
  1641.     STDMETHOD(SetContentExtent)(LPSIZEL pSize)
  1642.     {
  1643.         T* pT = static_cast<T*>(this);
  1644.         ATLTRACE2(atlTraceControls,2,_T("IQuickActivateImpl::SetContentExtent\n"));
  1645.         return pT->IOleObjectImpl<T>::SetExtent(DVASPECT_CONTENT, pSize);
  1646.     }
  1647.     STDMETHOD(GetContentExtent)(LPSIZEL pSize)
  1648.     {
  1649.         T* pT = static_cast<T*>(this);
  1650.         ATLTRACE2(atlTraceControls,2,_T("IQuickActivateImpl::GetContentExtent\n"));
  1651.         return pT->IOleObjectImpl<T>::GetExtent(DVASPECT_CONTENT, pSize);
  1652.     }
  1653. };
  1654.  
  1655.  
  1656. //////////////////////////////////////////////////////////////////////////////
  1657. // IOleObjectImpl
  1658. template <class T>
  1659. class ATL_NO_VTABLE IOleObjectImpl : public IOleObject
  1660. {
  1661. public:
  1662.     STDMETHOD(SetClientSite)(IOleClientSite *pClientSite)
  1663.     {
  1664.         T* pT = static_cast<T*>(this);
  1665.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::SetClientSite\n"));
  1666.         return pT->IOleObject_SetClientSite(pClientSite);
  1667.     }
  1668.     STDMETHOD(GetClientSite)(IOleClientSite **ppClientSite)
  1669.     {
  1670.         T* pT = static_cast<T*>(this);
  1671.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::GetClientSite\n"));
  1672.         return pT->IOleObject_GetClientSite(ppClientSite);
  1673.     }
  1674.     STDMETHOD(SetHostNames)(LPCOLESTR /* szContainerApp */, LPCOLESTR /* szContainerObj */)
  1675.     {
  1676.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::SetHostNames\n"));
  1677.         return S_OK;
  1678.     }
  1679.     STDMETHOD(Close)(DWORD dwSaveOption)
  1680.     {
  1681.         T* pT = static_cast<T*>(this);
  1682.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::Close\n"));
  1683.         return pT->IOleObject_Close(dwSaveOption);
  1684.     }
  1685.     STDMETHOD(SetMoniker)(DWORD /* dwWhichMoniker */, IMoniker* /* pmk */)
  1686.     {
  1687.         ATLTRACENOTIMPL(_T("IOleObjectImpl::SetMoniker"));
  1688.     }
  1689.     STDMETHOD(GetMoniker)(DWORD /* dwAssign */, DWORD /* dwWhichMoniker */, IMoniker** /* ppmk */)
  1690.     {
  1691.         ATLTRACENOTIMPL(_T("IOleObjectImpl::GetMoniker"));
  1692.     }
  1693.     STDMETHOD(InitFromData)(IDataObject* /* pDataObject */, BOOL /* fCreation */, DWORD /* dwReserved */)
  1694.     {
  1695.         ATLTRACENOTIMPL(_T("IOleObjectImpl::InitFromData"));
  1696.     }
  1697.     STDMETHOD(GetClipboardData)(DWORD /* dwReserved */, IDataObject** /* ppDataObject */)
  1698.     {
  1699.         ATLTRACENOTIMPL(_T("IOleObjectImpl::GetClipboardData"));
  1700.     }
  1701.  
  1702.     // Helpers for DoVerb - Over-rideable in user class
  1703.     HRESULT DoVerbPrimary(LPCRECT prcPosRect, HWND hwndParent)
  1704.     {
  1705.         T* pT = static_cast<T*>(this);
  1706.         BOOL bDesignMode = FALSE;
  1707.         CComVariant var;
  1708.         // if container doesn't support this property
  1709.         // don't allow design mode
  1710.         HRESULT hRes = pT->GetAmbientProperty(DISPID_AMBIENT_USERMODE, var);
  1711.         if (SUCCEEDED(hRes) && var.vt == VT_BOOL && !var.boolVal)
  1712.             bDesignMode = TRUE;
  1713.         if (bDesignMode)
  1714.             return pT->DoVerbProperties(prcPosRect, hwndParent);
  1715.         else
  1716.             return pT->DoVerbInPlaceActivate(prcPosRect, hwndParent);
  1717.     }
  1718.     HRESULT DoVerbShow(LPCRECT prcPosRect, HWND /* hwndParent */)
  1719.     {
  1720.         T* pT = static_cast<T*>(this);
  1721.         HRESULT hr;
  1722.         hr = pT->OnPreVerbShow();
  1723.         if (SUCCEEDED(hr))
  1724.         {
  1725.             hr = pT->InPlaceActivate(OLEIVERB_SHOW, prcPosRect);
  1726.             if (SUCCEEDED(hr))
  1727.                 hr = pT->OnPostVerbShow();
  1728.         }
  1729.         return hr;
  1730.     }
  1731.     HRESULT DoVerbInPlaceActivate(LPCRECT prcPosRect, HWND /* hwndParent */)
  1732.     {
  1733.         T* pT = static_cast<T*>(this);
  1734.         HRESULT hr;
  1735.         hr = pT->OnPreVerbInPlaceActivate();
  1736.         if (SUCCEEDED(hr))
  1737.         {
  1738.             hr = pT->InPlaceActivate(OLEIVERB_INPLACEACTIVATE, prcPosRect);
  1739.             if (SUCCEEDED(hr))
  1740.                 hr = pT->OnPostVerbInPlaceActivate();
  1741.             if (SUCCEEDED(hr))
  1742.                 pT->FireViewChange();
  1743.         }
  1744.         return hr;
  1745.     }
  1746.     HRESULT DoVerbUIActivate(LPCRECT prcPosRect, HWND /* hwndParent */)
  1747.     {
  1748.         T* pT = static_cast<T*>(this);
  1749.         HRESULT hr = S_OK;
  1750.         if (!pT->m_bUIActive)
  1751.         {
  1752.             hr = pT->OnPreVerbUIActivate();
  1753.             if (SUCCEEDED(hr))
  1754.             {
  1755.                 hr = pT->InPlaceActivate(OLEIVERB_UIACTIVATE, prcPosRect);
  1756.                 if (SUCCEEDED(hr))
  1757.                     hr = pT->OnPostVerbUIActivate();
  1758.             }
  1759.         }
  1760.         return hr;
  1761.     }
  1762.     HRESULT DoVerbHide(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  1763.     {
  1764.         T* pT = static_cast<T*>(this);
  1765.         HRESULT hr;
  1766.         hr = pT->OnPreVerbHide();
  1767.         if (SUCCEEDED(hr))
  1768.         {
  1769.             pT->UIDeactivate();
  1770.             if (pT->m_hWnd)
  1771.                 pT->ShowWindow(SW_HIDE);
  1772.             hr = pT->OnPostVerbHide();
  1773.         }
  1774.         return hr;
  1775.     }
  1776.     HRESULT DoVerbOpen(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  1777.     {
  1778.         T* pT = static_cast<T*>(this);
  1779.         HRESULT hr;
  1780.         hr = pT->OnPreVerbOpen();
  1781.         if (SUCCEEDED(hr))
  1782.             hr = pT->OnPostVerbOpen();
  1783.         return hr;
  1784.     }
  1785.     HRESULT DoVerbDiscardUndo(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  1786.     {
  1787.         T* pT = static_cast<T*>(this);
  1788.         HRESULT hr;
  1789.         hr = pT->OnPreVerbDiscardUndo();
  1790.         if (SUCCEEDED(hr))
  1791.             hr = pT->OnPostVerbDiscardUndo();
  1792.         return hr;
  1793.     }
  1794.     STDMETHOD(DoVerb)(LONG iVerb, LPMSG /* pMsg */, IOleClientSite* /* pActiveSite */, LONG /* lindex */,
  1795.                                      HWND hwndParent, LPCRECT lprcPosRect)
  1796.     {
  1797.         T* pT = static_cast<T*>(this);
  1798.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::DoVerb(%d)\n"), iVerb);
  1799.         ATLASSERT(pT->m_spClientSite);
  1800.  
  1801.         HRESULT hr = E_NOTIMPL;
  1802.         switch (iVerb)
  1803.         {
  1804.         case OLEIVERB_PRIMARY:
  1805.             hr = pT->DoVerbPrimary(lprcPosRect, hwndParent);
  1806.             break;
  1807.         case OLEIVERB_SHOW:
  1808.             hr = pT->DoVerbShow(lprcPosRect, hwndParent);
  1809.             break;
  1810.         case OLEIVERB_INPLACEACTIVATE:
  1811.             hr = pT->DoVerbInPlaceActivate(lprcPosRect, hwndParent);
  1812.             break;
  1813.         case OLEIVERB_UIACTIVATE:
  1814.             hr = pT->DoVerbUIActivate(lprcPosRect, hwndParent);
  1815.             break;
  1816.         case OLEIVERB_HIDE:
  1817.             hr = pT->DoVerbHide(lprcPosRect, hwndParent);
  1818.             break;
  1819.         case OLEIVERB_OPEN:
  1820.             hr = pT->DoVerbOpen(lprcPosRect, hwndParent);
  1821.             break;
  1822.         case OLEIVERB_DISCARDUNDOSTATE:
  1823.             hr = pT->DoVerbDiscardUndo(lprcPosRect, hwndParent);
  1824.             break;
  1825.         case OLEIVERB_PROPERTIES:
  1826.             hr = pT->DoVerbProperties(lprcPosRect, hwndParent);
  1827.         }
  1828.         return hr;
  1829.     }
  1830.     STDMETHOD(EnumVerbs)(IEnumOLEVERB **ppEnumOleVerb)
  1831.     {
  1832.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::EnumVerbs\n"));
  1833.         ATLASSERT(ppEnumOleVerb);
  1834.         if (!ppEnumOleVerb)
  1835.             return E_POINTER;
  1836.         return OleRegEnumVerbs(T::GetObjectCLSID(), ppEnumOleVerb);
  1837.     }
  1838.     STDMETHOD(Update)(void)
  1839.     {
  1840.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::Update\n"));
  1841.         return S_OK;
  1842.     }
  1843.     STDMETHOD(IsUpToDate)(void)
  1844.     {
  1845.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::IsUpToDate\n"));
  1846.         return S_OK;
  1847.     }
  1848.     STDMETHOD(GetUserClassID)(CLSID *pClsid)
  1849.     {
  1850.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::GetUserClassID\n"));
  1851.         ATLASSERT(pClsid);
  1852.         if (!pClsid)
  1853.             return E_POINTER;
  1854.         *pClsid = T::GetObjectCLSID();
  1855.         return S_OK;
  1856.     }
  1857.     STDMETHOD(GetUserType)(DWORD dwFormOfType, LPOLESTR *pszUserType)
  1858.     {
  1859.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::GetUserType\n"));
  1860.         return OleRegGetUserType(T::GetObjectCLSID(), dwFormOfType, pszUserType);
  1861.     }
  1862.     STDMETHOD(SetExtent)(DWORD dwDrawAspect, SIZEL *psizel)
  1863.     {
  1864.         T* pT = static_cast<T*>(this);
  1865.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::SetExtent\n"));
  1866.         return pT->IOleObject_SetExtent(dwDrawAspect, psizel);
  1867.     }
  1868.     STDMETHOD(GetExtent)(DWORD dwDrawAspect, SIZEL *psizel)
  1869.     {
  1870.         T* pT = static_cast<T*>(this);
  1871.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::GetExtent\n"));
  1872.         if (dwDrawAspect != DVASPECT_CONTENT)
  1873.             return E_FAIL;
  1874.         if (psizel == NULL)
  1875.             return E_POINTER;
  1876.         *psizel = pT->m_sizeExtent;
  1877.         return S_OK;
  1878.     }
  1879.     STDMETHOD(Advise)(IAdviseSink *pAdvSink, DWORD *pdwConnection)
  1880.     {
  1881.         T* pT = static_cast<T*>(this);
  1882.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::Advise\n"));
  1883.         return pT->IOleObject_Advise(pAdvSink, pdwConnection);
  1884.     }
  1885.     STDMETHOD(Unadvise)(DWORD dwConnection)
  1886.     {
  1887.         T* pT = static_cast<T*>(this);
  1888.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::Unadvise\n"));
  1889.         HRESULT hRes = E_FAIL;
  1890.         if (pT->m_spOleAdviseHolder != NULL)
  1891.             hRes = pT->m_spOleAdviseHolder->Unadvise(dwConnection);
  1892.         return hRes;
  1893.     }
  1894.     STDMETHOD(EnumAdvise)(IEnumSTATDATA **ppenumAdvise)
  1895.     {
  1896.         T* pT = static_cast<T*>(this);
  1897.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::EnumAdvise\n"));
  1898.         HRESULT hRes = E_FAIL;
  1899.         if (pT->m_spOleAdviseHolder != NULL)
  1900.             hRes = pT->m_spOleAdviseHolder->EnumAdvise(ppenumAdvise);
  1901.         return hRes;
  1902.     }
  1903.     STDMETHOD(GetMiscStatus)(DWORD dwAspect, DWORD *pdwStatus)
  1904.     {
  1905.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::GetMiscStatus\n"));
  1906.         return OleRegGetMiscStatus(T::GetObjectCLSID(), dwAspect, pdwStatus);
  1907.     }
  1908.     STDMETHOD(SetColorScheme)(LOGPALETTE* /* pLogpal */)
  1909.     {
  1910.         ATLTRACENOTIMPL(_T("IOleObjectImpl::SetColorScheme"));
  1911.     }
  1912. // Implementation
  1913. public:
  1914.     HRESULT OnPreVerbShow() { return S_OK; }
  1915.     HRESULT OnPostVerbShow() { return S_OK; }
  1916.     HRESULT OnPreVerbInPlaceActivate() { return S_OK; }
  1917.     HRESULT OnPostVerbInPlaceActivate() { return S_OK; }
  1918.     HRESULT OnPreVerbUIActivate() { return S_OK; }
  1919.     HRESULT OnPostVerbUIActivate() { return S_OK; }
  1920.     HRESULT OnPreVerbHide() { return S_OK; }
  1921.     HRESULT OnPostVerbHide() { return S_OK; }
  1922.     HRESULT OnPreVerbOpen() { return S_OK; }
  1923.     HRESULT OnPostVerbOpen() { return S_OK; }
  1924.     HRESULT OnPreVerbDiscardUndo() { return S_OK; }
  1925.     HRESULT OnPostVerbDiscardUndo() { return S_OK; }
  1926. };
  1927.  
  1928. //local struct used for implementation
  1929. #pragma pack(push, 1)
  1930. struct _ATL_DLGTEMPLATEEX
  1931. {
  1932.     WORD dlgVer;
  1933.     WORD signature;
  1934.     DWORD helpID;
  1935.     DWORD exStyle;
  1936.     DWORD style;
  1937.     WORD cDlgItems;
  1938.     short x;
  1939.     short y;
  1940.     short cx;
  1941.     short cy;
  1942. };
  1943. #pragma pack(pop)
  1944.  
  1945. //////////////////////////////////////////////////////////////////////////////
  1946. // IPropertyPageImpl
  1947. template <class T>
  1948. class ATL_NO_VTABLE IPropertyPageImpl : public IPropertyPage
  1949. {
  1950.  
  1951. public:
  1952.     void SetDirty(BOOL bDirty)
  1953.     {
  1954.         T* pT = static_cast<T*>(this);
  1955.         if (pT->m_bDirty != bDirty)
  1956.         {
  1957.             pT->m_bDirty = bDirty;
  1958.             pT->m_pPageSite->OnStatusChange(bDirty ? PROPPAGESTATUS_DIRTY | PROPPAGESTATUS_VALIDATE : 0);
  1959.         }
  1960.     }
  1961.  
  1962.     IPropertyPageImpl()
  1963.     {
  1964.         T* pT = static_cast<T*>(this);
  1965.         pT->m_pPageSite = NULL;
  1966.         pT->m_size.cx = 0;
  1967.         pT->m_size.cy = 0;
  1968.         pT->m_dwTitleID = 0;
  1969.         pT->m_dwHelpFileID = 0;
  1970.         pT->m_dwDocStringID = 0;
  1971.         pT->m_dwHelpContext = 0;
  1972.         pT->m_ppUnk = NULL;
  1973.         pT->m_nObjects = 0;
  1974.         pT->m_bDirty = FALSE;
  1975.         pT->m_hWnd = NULL;
  1976.     }
  1977.  
  1978.     ~IPropertyPageImpl()
  1979.     {
  1980.         T* pT = static_cast<T*>(this);
  1981.         if (pT->m_pPageSite != NULL)
  1982.             pT->m_pPageSite->Release();
  1983.  
  1984.         for (UINT i = 0; i < m_nObjects; i++)
  1985.             pT->m_ppUnk[i]->Release();
  1986.  
  1987.         delete[] pT->m_ppUnk;
  1988.     }
  1989.  
  1990.     // IPropertyPage
  1991.     //
  1992.     STDMETHOD(SetPageSite)(IPropertyPageSite *pPageSite)
  1993.     {
  1994.         T* pT = static_cast<T*>(this);
  1995.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::SetPageSite\n"));
  1996.  
  1997.         if (!pPageSite && pT->m_pPageSite)
  1998.         {
  1999.             pT->m_pPageSite->Release();
  2000.             pT->m_pPageSite = NULL;
  2001.             return S_OK;
  2002.         }
  2003.  
  2004.         if (!pPageSite && !pT->m_pPageSite)
  2005.             return S_OK;
  2006.  
  2007.         if (pPageSite && pT->m_pPageSite)
  2008.         {
  2009.             ATLTRACE2(atlTraceControls,2,_T("Error : setting page site again with non NULL value\n"));
  2010.             return E_UNEXPECTED;
  2011.         }
  2012.  
  2013.         pT->m_pPageSite = pPageSite;
  2014.         pT->m_pPageSite->AddRef();
  2015.         return S_OK;
  2016.     }
  2017.     STDMETHOD(Activate)(HWND hWndParent, LPCRECT pRect, BOOL /* bModal */)
  2018.     {
  2019.         T* pT = static_cast<T*>(this);
  2020.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Activate\n"));
  2021.  
  2022.         if (pRect == NULL)
  2023.         {
  2024.             ATLTRACE2(atlTraceControls,2,_T("Error : Passed a NULL rect\n"));
  2025.             return E_POINTER;
  2026.         }
  2027.  
  2028.         pT->m_hWnd = pT->Create(hWndParent);
  2029.         Move(pRect);
  2030.  
  2031.         m_size.cx = pRect->right - pRect->left;
  2032.         m_size.cy = pRect->bottom - pRect->top;
  2033.  
  2034.         return S_OK;
  2035.  
  2036.     }
  2037.     STDMETHOD(Deactivate)( void)
  2038.     {
  2039.         T* pT = static_cast<T*>(this);
  2040.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Deactivate\n"));
  2041.  
  2042.         if (pT->m_hWnd)
  2043.         {
  2044.             ATLTRACE2(atlTraceControls,2,_T("Destroying Dialog\n"));
  2045.             if (::IsWindow(pT->m_hWnd))
  2046.                 pT->DestroyWindow();
  2047.             pT->m_hWnd = NULL;
  2048.         }
  2049.  
  2050.         return S_OK;
  2051.  
  2052.     }
  2053.     STDMETHOD(GetPageInfo)(PROPPAGEINFO *pPageInfo)
  2054.     {
  2055.         T* pT = static_cast<T*>(this);
  2056.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::GetPageInfo\n"));
  2057.  
  2058.         if (pPageInfo == NULL)
  2059.         {
  2060.             ATLTRACE2(atlTraceControls,2,_T("Error : PROPPAGEINFO passed == NULL\n"));
  2061.             return E_POINTER;
  2062.         }
  2063.  
  2064.         HRSRC hRsrc = FindResource(_Module.GetResourceInstance(),
  2065.                                    MAKEINTRESOURCE(T::IDD), RT_DIALOG);
  2066.         if (hRsrc == NULL)
  2067.         {
  2068.             ATLTRACE2(atlTraceControls,2,_T("Could not find resource template\n"));
  2069.             return E_UNEXPECTED;
  2070.         }
  2071.  
  2072.         HGLOBAL hGlob = LoadResource(_Module.GetResourceInstance(), hRsrc);
  2073.         DLGTEMPLATE* pDlgTempl = (DLGTEMPLATE*)LockResource(hGlob);
  2074.         if (pDlgTempl == NULL)
  2075.         {
  2076.             ATLTRACE2(atlTraceControls,2,_T("Could not load resource template\n"));
  2077.             return E_UNEXPECTED;
  2078.         }
  2079.         AtlGetDialogSize(pDlgTempl, &m_size);
  2080.  
  2081.         pPageInfo->cb = sizeof(PROPPAGEINFO);
  2082.         pPageInfo->pszTitle = LoadStringHelper(pT->m_dwTitleID);
  2083.         pPageInfo->size = m_size;
  2084.         pPageInfo->pszHelpFile = LoadStringHelper(pT->m_dwHelpFileID);
  2085.         pPageInfo->pszDocString = LoadStringHelper(pT->m_dwDocStringID);
  2086.         pPageInfo->dwHelpContext = pT->m_dwHelpContext;
  2087.  
  2088.         return S_OK;
  2089.     }
  2090.  
  2091.     STDMETHOD(SetObjects)(ULONG nObjects, IUnknown **ppUnk)
  2092.     {
  2093.         T* pT = static_cast<T*>(this);
  2094.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::SetObjects\n"));
  2095.  
  2096.         if (ppUnk == NULL)
  2097.             return E_POINTER;
  2098.  
  2099.         if (pT->m_ppUnk != NULL && pT->m_nObjects > 0)
  2100.         {
  2101.             for (UINT iObj = 0; iObj < pT->m_nObjects; iObj++)
  2102.                 pT->m_ppUnk[iObj]->Release();
  2103.  
  2104.             delete [] pT->m_ppUnk;
  2105.         }
  2106.  
  2107.         pT->m_ppUnk = NULL;
  2108.         ATLTRY(pT->m_ppUnk = new IUnknown*[nObjects]);
  2109.  
  2110.         if (pT->m_ppUnk == NULL)
  2111.             return E_OUTOFMEMORY;
  2112.  
  2113.         for (UINT i = 0; i < nObjects; i++)
  2114.         {
  2115.             ppUnk[i]->AddRef();
  2116.             pT->m_ppUnk[i] = ppUnk[i];
  2117.         }
  2118.  
  2119.         pT->m_nObjects = nObjects;
  2120.  
  2121.         return S_OK;
  2122.     }
  2123.     STDMETHOD(Show)(UINT nCmdShow)
  2124.     {
  2125.         T* pT = static_cast<T*>(this);
  2126.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Show\n"));
  2127.  
  2128.         if (pT->m_hWnd == NULL)
  2129.             return E_UNEXPECTED;
  2130.  
  2131.         ShowWindow(pT->m_hWnd, nCmdShow);
  2132.         return S_OK;
  2133.     }
  2134.     STDMETHOD(Move)(LPCRECT pRect)
  2135.     {
  2136.         T* pT = static_cast<T*>(this);
  2137.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Move\n"));
  2138.  
  2139.         if (pT->m_hWnd == NULL)
  2140.             return E_UNEXPECTED;
  2141.  
  2142.         if (pRect == NULL)
  2143.             return E_POINTER;
  2144.  
  2145.         MoveWindow(pT->m_hWnd, pRect->left, pRect->top, pRect->right - pRect->left,
  2146.                  pRect->bottom - pRect->top, TRUE);
  2147.  
  2148.         return S_OK;
  2149.  
  2150.     }
  2151.     STDMETHOD(IsPageDirty)(void)
  2152.     {
  2153.         T* pT = static_cast<T*>(this);
  2154.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::IsPageDirty\n"));
  2155.         return pT->m_bDirty ? S_OK : S_FALSE;
  2156.     }
  2157.     STDMETHOD(Apply)(void)
  2158.     {
  2159.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Apply\n"));
  2160.         return S_OK;
  2161.     }
  2162.     STDMETHOD(Help)(LPCOLESTR pszHelpDir)
  2163.     {
  2164.         T* pT = static_cast<T*>(this);
  2165.         USES_CONVERSION;
  2166.  
  2167.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Help\n"));
  2168.         CComBSTR szFullFileName(pszHelpDir);
  2169.         LPOLESTR szFileName = LoadStringHelper(pT->m_dwHelpFileID);
  2170.         szFullFileName.Append(OLESTR("\\"));
  2171.         szFullFileName.Append(szFileName);
  2172.         CoTaskMemFree(szFileName);
  2173.         WinHelp(pT->m_hWnd, OLE2CT(szFullFileName), HELP_CONTEXTPOPUP, NULL);
  2174.         return S_OK;
  2175.     }
  2176.     STDMETHOD(TranslateAccelerator)(MSG *pMsg)
  2177.     {
  2178.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::TranslateAccelerator\n"));
  2179.         T* pT = static_cast<T*>(this);
  2180.         if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) &&
  2181.             (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST))
  2182.             return S_FALSE;
  2183.  
  2184.         return (IsDialogMessage(pT->m_hWnd, pMsg)) ? S_OK : S_FALSE;
  2185.     }
  2186.  
  2187.     IPropertyPageSite* m_pPageSite;
  2188.     IUnknown** m_ppUnk;
  2189.     ULONG m_nObjects;
  2190.     SIZE m_size;
  2191.     UINT m_dwTitleID;
  2192.     UINT m_dwHelpFileID;
  2193.     UINT m_dwDocStringID;
  2194.     DWORD m_dwHelpContext;
  2195.     BOOL m_bDirty;
  2196.  
  2197. //methods
  2198. public:
  2199.  
  2200.     BEGIN_MSG_MAP(IPropertyPageImpl<T>)
  2201.         MESSAGE_HANDLER(WM_STYLECHANGING, OnStyleChange)
  2202.     END_MSG_MAP()
  2203.  
  2204.     LRESULT OnStyleChange(UINT, WPARAM wParam, LPARAM lParam, BOOL&)
  2205.     {
  2206.         if (wParam == GWL_EXSTYLE)
  2207.         {
  2208.             LPSTYLESTRUCT lpss = (LPSTYLESTRUCT) lParam;
  2209.             lpss->styleNew |= WS_EX_CONTROLPARENT;
  2210.             return 0;
  2211.         }
  2212.         return 1;
  2213.     }
  2214.  
  2215.     LPOLESTR LoadStringHelper(UINT idRes)
  2216.     {
  2217.         USES_CONVERSION;
  2218.  
  2219.         TCHAR szTemp[_MAX_PATH];
  2220.         LPOLESTR sz;
  2221.         sz = (LPOLESTR)CoTaskMemAlloc(_MAX_PATH*sizeof(OLECHAR));
  2222.         if (sz == NULL)
  2223.             return NULL;
  2224.         sz[0] = NULL;
  2225.  
  2226.         if (LoadString(_Module.GetResourceInstance(), idRes, szTemp, _MAX_PATH))
  2227.             ocscpy(sz, T2OLE(szTemp));
  2228.         else
  2229.         {
  2230.             ATLTRACE2(atlTraceControls,2,_T("Error : Failed to load string from res\n"));
  2231.         }
  2232.  
  2233.         return sz;
  2234.     }
  2235. };
  2236.  
  2237.  
  2238. //////////////////////////////////////////////////////////////////////////////
  2239. // IPropertyPage2Impl
  2240. template <class T>
  2241. class ATL_NO_VTABLE IPropertyPage2Impl : public IPropertyPageImpl<T>
  2242. {
  2243. public:
  2244.  
  2245.     STDMETHOD(EditProperty)(DISPID dispID)
  2246.     {
  2247.         ATLTRACENOTIMPL(_T("IPropertyPage2Impl::EditProperty\n"));
  2248.     }
  2249. };
  2250.  
  2251.  
  2252.  
  2253. //////////////////////////////////////////////////////////////////////////////
  2254. // IPerPropertyBrowsingImpl
  2255. template <class T>
  2256. class ATL_NO_VTABLE IPerPropertyBrowsingImpl : public IPerPropertyBrowsing
  2257. {
  2258. public:
  2259.     STDMETHOD(GetDisplayString)(DISPID dispID,BSTR *pBstr)
  2260.     {
  2261.         ATLTRACE2(atlTraceControls,2,_T("IPerPropertyBrowsingImpl::GetDisplayString\n"));
  2262.         T* pT = static_cast<T*>(this);
  2263.         *pBstr = NULL;
  2264.         CComVariant var;
  2265.         if (FAILED(CComDispatchDriver::GetProperty(pT, dispID, &var)))
  2266.             return S_FALSE;
  2267.  
  2268.         BSTR bstrTemp = var.bstrVal;
  2269.         if (var.vt != VT_BSTR)
  2270.         {
  2271.             CComVariant varDest;
  2272.             if (FAILED(::VariantChangeType(&varDest, &var, VARIANT_NOVALUEPROP, VT_BSTR)))
  2273.                 return S_FALSE;
  2274.             bstrTemp = varDest.bstrVal;
  2275.         }
  2276.         *pBstr = SysAllocString(bstrTemp);
  2277.         if (*pBstr == NULL)
  2278.             return E_OUTOFMEMORY;
  2279.         return S_OK;
  2280.     }
  2281.  
  2282.     STDMETHOD(MapPropertyToPage)(DISPID dispID, CLSID *pClsid)
  2283.     {
  2284.         ATLTRACE2(atlTraceControls,2,_T("IPerPropertyBrowsingImpl::MapPropertyToPage\n"));
  2285.         ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
  2286.         ATLASSERT(pMap != NULL);
  2287.         for (int i = 0; pMap[i].pclsidPropPage != NULL; i++)
  2288.         {
  2289.             if (pMap[i].szDesc == NULL)
  2290.                 continue;
  2291.  
  2292.             // reject data entry types
  2293.             if (pMap[i].dwSizeData != 0)
  2294.                 continue;
  2295.  
  2296.             if (pMap[i].dispid == dispID)
  2297.             {
  2298.                 ATLASSERT(pMap[i].pclsidPropPage != NULL);
  2299.                 *pClsid = *(pMap[i].pclsidPropPage);
  2300.                 return S_OK;
  2301.             }
  2302.         }
  2303.         *pClsid = CLSID_NULL;
  2304.         return E_INVALIDARG;
  2305.     }
  2306.     STDMETHOD(GetPredefinedStrings)(DISPID dispID, CALPOLESTR *pCaStringsOut,CADWORD *pCaCookiesOut)
  2307.     {
  2308.         dispID;
  2309.         ATLTRACE2(atlTraceControls,2,_T("IPerPropertyBrowsingImpl::GetPredefinedStrings\n"));
  2310.         if (pCaStringsOut == NULL || pCaCookiesOut == NULL)
  2311.             return E_POINTER;
  2312.  
  2313.         pCaStringsOut->cElems = 0;
  2314.         pCaStringsOut->pElems = NULL;
  2315.         pCaCookiesOut->cElems = 0;
  2316.         pCaCookiesOut->pElems = NULL;
  2317.         return S_OK;
  2318.     }
  2319.     STDMETHOD(GetPredefinedValue)(DISPID /*dispID*/, DWORD /*dwCookie*/, VARIANT* /*pVarOut*/)
  2320.     {
  2321.         ATLTRACENOTIMPL(_T("IPerPropertyBrowsingImpl::GetPredefinedValue"));
  2322.     }
  2323. };
  2324.  
  2325. //////////////////////////////////////////////////////////////////////////////
  2326. // IViewObjectExImpl
  2327. template <class T>
  2328. class ATL_NO_VTABLE IViewObjectExImpl : public IViewObjectEx
  2329. {
  2330. public:
  2331.     STDMETHOD(Draw)(DWORD dwDrawAspect, LONG lindex, void *pvAspect,
  2332.                     DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw,
  2333.                     LPCRECTL prcBounds, LPCRECTL prcWBounds,
  2334.                     BOOL (__stdcall * /*pfnContinue*/)(DWORD dwContinue),
  2335.                     DWORD /*dwContinue*/)
  2336.     {
  2337.         T* pT = static_cast<T*>(this);
  2338.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::Draw\n"));
  2339.         return pT->IViewObject_Draw(dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, hdcDraw,
  2340.             prcBounds, prcWBounds);
  2341.     }
  2342.  
  2343.     STDMETHOD(GetColorSet)(DWORD /* dwDrawAspect */,LONG /* lindex */, void* /* pvAspect */, DVTARGETDEVICE* /* ptd */, HDC /* hicTargetDev */, LOGPALETTE** /* ppColorSet */)
  2344.     {
  2345.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::GetColorSet"));
  2346.     }
  2347.     STDMETHOD(Freeze)(DWORD /* dwDrawAspect */, LONG /* lindex */, void* /* pvAspect */,DWORD* /* pdwFreeze */)
  2348.     {
  2349.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::Freeze"));
  2350.     }
  2351.     STDMETHOD(Unfreeze)(DWORD /* dwFreeze */)
  2352.     {
  2353.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::Unfreeze"));
  2354.     }
  2355.     STDMETHOD(SetAdvise)(DWORD /* aspects */, DWORD /* advf */, IAdviseSink* pAdvSink)
  2356.     {
  2357.         T* pT = static_cast<T*>(this);
  2358.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::SetAdvise\n"));
  2359.         pT->m_spAdviseSink = pAdvSink;
  2360.         return S_OK;
  2361.     }
  2362.     STDMETHOD(GetAdvise)(DWORD* /* pAspects */, DWORD* /* pAdvf */, IAdviseSink** ppAdvSink)
  2363.     {
  2364.         T* pT = static_cast<T*>(this);
  2365.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::GetAdvise\n"));
  2366.         if (ppAdvSink != NULL)
  2367.         {
  2368.             *ppAdvSink = pT->m_spAdviseSink;
  2369.             if (pT->m_spAdviseSink)
  2370.                 pT->m_spAdviseSink.p->AddRef();
  2371.         }
  2372.         return S_OK;
  2373.     }
  2374.  
  2375.     // IViewObject2
  2376.     //
  2377.     STDMETHOD(GetExtent)(DWORD /* dwDrawAspect */, LONG /* lindex */, DVTARGETDEVICE* /* ptd */, LPSIZEL lpsizel)
  2378.     {
  2379.         T* pT = static_cast<T*>(this);
  2380.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::GetExtent\n"));
  2381.         *lpsizel = pT->m_sizeExtent;
  2382.         return S_OK;
  2383.     }
  2384.  
  2385.     // IViewObjectEx
  2386.     //
  2387.     STDMETHOD(GetRect)(DWORD /* dwAspect */, LPRECTL /* pRect */)
  2388.     {
  2389.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::GetRect"));
  2390.     }
  2391.  
  2392.     STDMETHOD(GetViewStatus)(DWORD* pdwStatus)
  2393.     {
  2394.         T* pT = static_cast<T*>(this);
  2395.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::GetViewStatus\n"));
  2396.         *pdwStatus = pT->_GetViewStatus();
  2397.         return S_OK;
  2398.     }
  2399.     STDMETHOD(QueryHitPoint)(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG /* lCloseHint */, DWORD *pHitResult)
  2400.     {
  2401.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::QueryHitPoint\n"));
  2402.         if (dwAspect == DVASPECT_CONTENT)
  2403.         {
  2404.             *pHitResult = PtInRect(pRectBounds, ptlLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  2405.             return S_OK;
  2406.         }
  2407.         ATLTRACE2(atlTraceControls,2,_T("Wrong DVASPECT\n"));
  2408.         return E_FAIL;
  2409.     }
  2410.     STDMETHOD(QueryHitRect)(DWORD dwAspect, LPCRECT pRectBounds, LPCRECT prcLoc, LONG /* lCloseHint */, DWORD* pHitResult)
  2411.     {
  2412.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::QueryHitRect\n"));
  2413.         if (dwAspect == DVASPECT_CONTENT)
  2414.         {
  2415.             RECT rc;
  2416.             *pHitResult = UnionRect(&rc, pRectBounds, prcLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  2417.             return S_OK;
  2418.         }
  2419.         ATLTRACE2(atlTraceControls,2,_T("Wrong DVASPECT\n"));
  2420.         return E_FAIL;
  2421.     }
  2422.     STDMETHOD(GetNaturalExtent)(DWORD dwAspect, LONG /* lindex */, DVTARGETDEVICE* /* ptd */, HDC /* hicTargetDev */, DVEXTENTINFO* pExtentInfo , LPSIZEL psizel)
  2423.     {
  2424.         T* pT = static_cast<T*>(this);
  2425.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::GetNaturalExtent\n"));
  2426.         HRESULT hRes = E_FAIL;
  2427.         if (pExtentInfo == NULL || psizel == NULL)
  2428.             hRes = E_POINTER;
  2429.         else if (dwAspect == DVASPECT_CONTENT)
  2430.         {
  2431.             if (pExtentInfo->dwExtentMode == DVEXTENT_CONTENT)
  2432.             {
  2433.                 *psizel = pT->m_sizeNatural;
  2434.                 hRes = S_OK;
  2435.             }
  2436.         }
  2437.         return hRes;
  2438.     }
  2439.  
  2440. public:
  2441. };
  2442.  
  2443. //////////////////////////////////////////////////////////////////////////////
  2444. // IOleInPlaceObjectWindowlessImpl
  2445. //
  2446. template <class T>
  2447. class ATL_NO_VTABLE IOleInPlaceObjectWindowlessImpl : public IOleInPlaceObjectWindowless
  2448. {
  2449. public:
  2450.     // IOleWindow
  2451.     //
  2452.  
  2453.     // Change IOleInPlaceActiveObject::GetWindow as well
  2454.     STDMETHOD(GetWindow)(HWND* phwnd)
  2455.     {
  2456.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceObjectWindowlessImpl::GetWindow\n"));
  2457.         T* pT = static_cast<T*>(this);
  2458.         HRESULT hRes = E_POINTER;
  2459.  
  2460.         if (pT->m_bWasOnceWindowless)
  2461.             return E_FAIL;
  2462.  
  2463.         if (phwnd != NULL)
  2464.         {
  2465.             *phwnd = pT->m_hWnd;
  2466.             hRes = (*phwnd == NULL) ? E_UNEXPECTED : S_OK;
  2467.         }
  2468.         return hRes;
  2469.     }
  2470.     STDMETHOD(ContextSensitiveHelp)(BOOL /* fEnterMode */)
  2471.     {
  2472.         ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::ContextSensitiveHelp"));
  2473.     }
  2474.  
  2475.     // IOleInPlaceObject
  2476.     //
  2477.     STDMETHOD(InPlaceDeactivate)(void)
  2478.     {
  2479.         T* pT = static_cast<T*>(this);
  2480.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceObjectWindowlessImpl::InPlaceDeactivate\n"));
  2481.         return pT->IOleInPlaceObject_InPlaceDeactivate();
  2482.     }
  2483.     STDMETHOD(UIDeactivate)(void)
  2484.     {
  2485.         T* pT = static_cast<T*>(this);
  2486.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceObjectWindowlessImpl::UIDeactivate\n"));
  2487.         return pT->IOleInPlaceObject_UIDeactivate();
  2488.     }
  2489.     STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip)
  2490.     {
  2491.         T* pT = static_cast<T*>(this);
  2492.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceObjectWindowlessImpl::SetObjectRects\n"));
  2493.         return pT->IOleInPlaceObject_SetObjectRects(prcPos, prcClip);
  2494.     }
  2495.     STDMETHOD(ReactivateAndUndo)(void)
  2496.     {
  2497.         ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::ReactivateAndUndo"));
  2498.     }
  2499.  
  2500.     // IOleInPlaceObjectWindowless
  2501.     //
  2502.     STDMETHOD(OnWindowMessage)(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
  2503.     {
  2504.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceObjectWindowlessImpl::OnWindowMessage\n"));
  2505.         T* pT = static_cast<T*>(this);
  2506.         BOOL b = pT->ProcessWindowMessage(pT->m_hWnd, msg, wParam, lParam, *plResult);
  2507.         return b ? S_OK : S_FALSE;
  2508.     }
  2509.  
  2510.     STDMETHOD(GetDropTarget)(IDropTarget** /* ppDropTarget */)
  2511.     {
  2512.         ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::GetDropTarget"));
  2513.     }
  2514. };
  2515.  
  2516.  
  2517. //////////////////////////////////////////////////////////////////////////////
  2518. // IOleInPlaceActiveObjectImpl
  2519. //
  2520. template <class T>
  2521. class ATL_NO_VTABLE IOleInPlaceActiveObjectImpl : public IOleInPlaceActiveObject
  2522. {
  2523. public:
  2524.     // IOleWindow
  2525.     //
  2526.  
  2527.     // Change IOleInPlaceObjectWindowless::GetWindow as well
  2528.     STDMETHOD(GetWindow)(HWND *phwnd)
  2529.     {
  2530.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::GetWindow\n"));
  2531.         T* pT = static_cast<T*>(this);
  2532.         HRESULT hRes = E_POINTER;
  2533.  
  2534.         if (pT->m_bWasOnceWindowless)
  2535.             return E_FAIL;
  2536.  
  2537.         if (phwnd != NULL)
  2538.         {
  2539.             *phwnd = pT->m_hWnd;
  2540.             hRes = (*phwnd == NULL) ? E_UNEXPECTED : S_OK;
  2541.         }
  2542.         return hRes;
  2543.     }
  2544.     STDMETHOD(ContextSensitiveHelp)(BOOL /* fEnterMode */)
  2545.     {
  2546.         ATLTRACENOTIMPL(_T("IOleInPlaceActiveObjectImpl::ContextSensitiveHelp"));
  2547.     }
  2548.  
  2549.     // IOleInPlaceActiveObject
  2550.     //
  2551.     STDMETHOD(TranslateAccelerator)(LPMSG pMsg)
  2552.     {
  2553.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::TranslateAccelerator\n"));
  2554.         T* pT = static_cast<T*>(this);
  2555.         HRESULT hRet = S_OK;
  2556.         if (pT->PreTranslateAccelerator(pMsg, hRet))
  2557.             return hRet;
  2558.         CComPtr<IOleControlSite> spCtlSite;
  2559.         hRet = pT->InternalGetSite(IID_IOleControlSite, (void**)&spCtlSite);
  2560.         if (SUCCEEDED(hRet))
  2561.         {
  2562.             if (spCtlSite != NULL)
  2563.             {
  2564.                 DWORD dwKeyMod = 0;
  2565.                 if (::GetKeyState(VK_SHIFT) < 0)
  2566.                     dwKeyMod += 1;    // KEYMOD_SHIFT
  2567.                 if (::GetKeyState(VK_CONTROL) < 0)
  2568.                     dwKeyMod += 2;    // KEYMOD_CONTROL
  2569.                 if (::GetKeyState(VK_MENU) < 0)
  2570.                     dwKeyMod += 4;    // KEYMOD_ALT
  2571.                 hRet = spCtlSite->TranslateAccelerator(pMsg, dwKeyMod);
  2572.             }
  2573.             else
  2574.                 hRet = S_FALSE;
  2575.         }
  2576.         return (hRet == S_OK) ? S_OK : S_FALSE;
  2577.     }
  2578.     STDMETHOD(OnFrameWindowActivate)(BOOL /* fActivate */)
  2579.     {
  2580.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::OnFrameWindowActivate\n"));
  2581.         return S_OK;
  2582.     }
  2583.     STDMETHOD(OnDocWindowActivate)(BOOL fActivate)
  2584.     {
  2585.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::OnDocWindowActivate\n"));
  2586.         T* pT = static_cast<T*>(this);
  2587.         if (fActivate == FALSE)
  2588.             pT->IOleInPlaceObject_UIDeactivate();
  2589.         return S_OK;
  2590.     }
  2591.     STDMETHOD(ResizeBorder)(LPCRECT /* prcBorder */, IOleInPlaceUIWindow* /* pUIWindow */, BOOL /* fFrameWindow */)
  2592.     {
  2593.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::ResizeBorder\n"));
  2594.         return S_OK;
  2595.     }
  2596.     STDMETHOD(EnableModeless)(BOOL /* fEnable */)
  2597.     {
  2598.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::EnableModeless\n"));
  2599.         return S_OK;
  2600.     }
  2601. };
  2602.  
  2603. //////////////////////////////////////////////////////////////////////////////
  2604. // IPointerInactiveImpl
  2605. template <class T>
  2606. class ATL_NO_VTABLE IPointerInactiveImpl : public IPointerInactive
  2607. {
  2608. public:
  2609.     // IPointerInactive
  2610.     //
  2611.     STDMETHOD(GetActivationPolicy)(DWORD *pdwPolicy)
  2612.     {
  2613.         ATLTRACENOTIMPL(_T("IPointerInactiveImpl::GetActivationPolicy"));
  2614.     }
  2615.     STDMETHOD(OnInactiveMouseMove)(LPCRECT pRectBounds, long x, long y, DWORD dwMouseMsg)
  2616.     {
  2617.         ATLTRACENOTIMPL(_T("IPointerInactiveImpl::OnInactiveMouseMove"));
  2618.     }
  2619.     STDMETHOD(OnInactiveSetCursor)(LPCRECT pRectBounds, long x, long y, DWORD dwMouseMsg, BOOL fSetAlways)
  2620.     {
  2621.         ATLTRACENOTIMPL(_T("IPointerInactiveImpl::OnInactiveSetCursor"));
  2622.     }
  2623. };
  2624.  
  2625. //////////////////////////////////////////////////////////////////////////////
  2626. // IRunnableObjectImpl
  2627. template <class T>
  2628. class ATL_NO_VTABLE IRunnableObjectImpl : public IRunnableObject
  2629. {
  2630. public:
  2631.     // IRunnableObject
  2632.     //
  2633.     STDMETHOD(GetRunningClass)(LPCLSID lpClsid)
  2634.     {
  2635.         ATLTRACE2(atlTraceControls,2,_T("IRunnableObjectImpl::GetRunningClass\n"));
  2636.         *lpClsid = GUID_NULL;
  2637.         return E_UNEXPECTED;
  2638.     }
  2639.     STDMETHOD(Run)(LPBINDCTX)
  2640.     {
  2641.         ATLTRACE2(atlTraceControls,2,_T("IRunnableObjectImpl::Run\n"));
  2642.         return S_OK;
  2643.     }
  2644.     virtual BOOL STDMETHODCALLTYPE IsRunning()
  2645.     {
  2646.         ATLTRACE2(atlTraceControls,2,_T("IRunnableObjectImpl::IsRunning\n"));
  2647.         return TRUE;
  2648.     }
  2649.     STDMETHOD(LockRunning)(BOOL /*fLock*/, BOOL /*fLastUnlockCloses*/)
  2650.     {
  2651.         ATLTRACE2(atlTraceControls,2,_T("IRunnableObjectImpl::LockRunning\n"));
  2652.         return S_OK;
  2653.     }
  2654.     STDMETHOD(SetContainedObject)(BOOL /*fContained*/)
  2655.     {
  2656.         ATLTRACE2(atlTraceControls,2,_T("IRunnableObjectImpl::SetContainedObject\n"));
  2657.         return S_OK;
  2658.     }
  2659. };
  2660.  
  2661.  
  2662. //////////////////////////////////////////////////////////////////////////////
  2663. // IDataObjectImpl
  2664. template <class T>
  2665. class ATL_NO_VTABLE IDataObjectImpl : public IDataObject
  2666. {
  2667. public:
  2668.     STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
  2669.     {
  2670.         ATLTRACE2(atlTraceControls,2,_T("IDataObjectImpl::GetData\n"));
  2671.         T* pT = (T*) this;
  2672.         return pT->IDataObject_GetData(pformatetcIn, pmedium);
  2673.     }
  2674.     STDMETHOD(GetDataHere)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */)
  2675.     {
  2676.         ATLTRACENOTIMPL(_T("IDataObjectImpl::GetDataHere"));
  2677.     }
  2678.     STDMETHOD(QueryGetData)(FORMATETC* /* pformatetc */)
  2679.     {
  2680.         ATLTRACENOTIMPL(_T("IDataObjectImpl::QueryGetData"));
  2681.     }
  2682.     STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */)
  2683.     {
  2684.         ATLTRACENOTIMPL(_T("IDataObjectImpl::GetCanonicalFormatEtc"));
  2685.     }
  2686.     STDMETHOD(SetData)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */)
  2687.     {
  2688.         ATLTRACENOTIMPL(_T("IDataObjectImpl::SetData"));
  2689.     }
  2690.     STDMETHOD(EnumFormatEtc)(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */)
  2691.     {
  2692.         ATLTRACENOTIMPL(_T("IDataObjectImpl::EnumFormatEtc"));
  2693.     }
  2694.     STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink,
  2695.         DWORD *pdwConnection)
  2696.     {
  2697.         ATLTRACE2(atlTraceControls,2,_T("IDataObjectImpl::DAdvise\n"));
  2698.         T* pT = static_cast<T*>(this);
  2699.         HRESULT hr = S_OK;
  2700.         if (pT->m_spDataAdviseHolder == NULL)
  2701.             hr = CreateDataAdviseHolder(&pT->m_spDataAdviseHolder);
  2702.  
  2703.         if (hr == S_OK)
  2704.             hr = pT->m_spDataAdviseHolder->Advise((IDataObject*)this, pformatetc, advf, pAdvSink, pdwConnection);
  2705.  
  2706.         return hr;
  2707.     }
  2708.     STDMETHOD(DUnadvise)(DWORD dwConnection)
  2709.     {
  2710.         ATLTRACE2(atlTraceControls,2,_T("IDataObjectImpl::DUnadvise\n"));
  2711.         T* pT = static_cast<T*>(this);
  2712.         HRESULT hr = S_OK;
  2713.         if (pT->m_spDataAdviseHolder == NULL)
  2714.             hr = OLE_E_NOCONNECTION;
  2715.         else
  2716.             hr = pT->m_spDataAdviseHolder->Unadvise(dwConnection);
  2717.         return hr;
  2718.     }
  2719.     STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise)
  2720.     {
  2721.         ATLTRACE2(atlTraceControls,2,_T("IDataObjectImpl::EnumDAdvise\n"));
  2722.         T* pT = static_cast<T*>(this);
  2723.         HRESULT hr = E_FAIL;
  2724.         if (pT->m_spDataAdviseHolder != NULL)
  2725.             hr = pT->m_spDataAdviseHolder->EnumAdvise(ppenumAdvise);
  2726.         return hr;
  2727.     }
  2728. };
  2729.  
  2730. //////////////////////////////////////////////////////////////////////////////
  2731. // IPropertyNotifySinkCP
  2732. template <class T, class CDV = CComDynamicUnkArray >
  2733. class ATL_NO_VTABLE IPropertyNotifySinkCP :
  2734.     public IConnectionPointImpl<T, &IID_IPropertyNotifySink, CDV>
  2735. {
  2736. public:
  2737.     typedef CFirePropNotifyEvent _ATL_PROP_NOTIFY_EVENT_CLASS;
  2738. };
  2739.  
  2740.  
  2741. //////////////////////////////////////////////////////////////////////////////
  2742. // IObjectSafety
  2743. //
  2744. // 2nd template parameter is the supported safety e.g.
  2745. // INTERFACESAFE_FOR_UNTRUSTED_CALLER - safe for scripting
  2746. // INTERFACESAFE_FOR_UNTRUSTED_DATA   - safe for initialization from data
  2747.  
  2748. template <class T, DWORD dwSupportedSafety>
  2749. class ATL_NO_VTABLE IObjectSafetyImpl : public IObjectSafety
  2750. {
  2751. public:
  2752.     IObjectSafetyImpl()
  2753.     {
  2754.         m_dwCurrentSafety = 0;
  2755.     }
  2756.  
  2757.     STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
  2758.     {
  2759.         ATLTRACE2(atlTraceControls,2,_T("IObjectSafetyImpl2::GetInterfaceSafetyOptions\n"));
  2760.         T* pT = static_cast<T*>(this);
  2761.         if (pdwSupportedOptions == NULL || pdwEnabledOptions == NULL)
  2762.             return E_POINTER;
  2763.         
  2764.         HRESULT hr;
  2765.         IUnknown* pUnk;
  2766.         // Check if we support this interface
  2767.         hr = pT->GetUnknown()->QueryInterface(riid, (void**)&pUnk);
  2768.         if (SUCCEEDED(hr))
  2769.         {
  2770.             // We support this interface so set the safety options accordingly
  2771.             pUnk->Release();    // Release the interface we just acquired
  2772.             *pdwSupportedOptions = dwSupportedSafety;
  2773.             *pdwEnabledOptions   = m_dwCurrentSafety;
  2774.         }
  2775.         else
  2776.         {
  2777.             // We don't support this interface
  2778.             *pdwSupportedOptions = 0;
  2779.             *pdwEnabledOptions   = 0;
  2780.         }
  2781.         return hr;
  2782.     }
  2783.     STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
  2784.     {
  2785.         ATLTRACE2(atlTraceControls,2,_T("IObjectSafetyImpl2::SetInterfaceSafetyOptions\n"));
  2786.         T* pT = static_cast<T*>(this);
  2787.         IUnknown* pUnk;
  2788.         
  2789.         // Check if we support the interface and return E_NOINTEFACE if we don't
  2790.         if (FAILED(pT->GetUnknown()->QueryInterface(riid, (void**)&pUnk)))
  2791.             return E_NOINTERFACE;
  2792.         pUnk->Release();    // Release the interface we just acquired
  2793.         
  2794.         // If we are asked to set options we don't support then fail
  2795.         if (dwOptionSetMask & ~dwSupportedSafety)
  2796.             return E_FAIL;
  2797.  
  2798.         // Set the safety options we have been asked to
  2799.         m_dwCurrentSafety = m_dwCurrentSafety  & ~dwEnabledOptions | dwOptionSetMask;
  2800.         return S_OK;
  2801.     }
  2802.     DWORD m_dwCurrentSafety;
  2803. };
  2804.  
  2805. template <class T>
  2806. class ATL_NO_VTABLE IOleLinkImpl : public IOleLink
  2807. {
  2808.     STDMETHOD(SetUpdateOptions)(DWORD /* dwUpdateOpt */)
  2809.     {
  2810.         ATLTRACENOTIMPL(_T("IOleLinkImpl::SetUpdateOptions"));
  2811.     }
  2812.  
  2813.     STDMETHOD(GetUpdateOptions)(DWORD* /* pdwUpdateOpt */)
  2814.     {
  2815.         ATLTRACENOTIMPL(_T("IOleLinkImpl::GetUpdateOptions"));
  2816.     }
  2817.  
  2818.     STDMETHOD(SetSourceMoniker)(IMoniker* /* pmk */, REFCLSID /* rclsid */)
  2819.     {
  2820.         ATLTRACENOTIMPL(_T("IOleLinkImpl::SetSourceMoniker"));
  2821.     }
  2822.  
  2823.     STDMETHOD(GetSourceMoniker)(IMoniker** /* ppmk */)
  2824.     {
  2825.         ATLTRACENOTIMPL(_T("IOleLinkImpl::GetSourceMoniker"));
  2826.     };
  2827.  
  2828.     STDMETHOD(SetSourceDisplayName)(LPCOLESTR /* pszStatusText */)
  2829.     {
  2830.         ATLTRACENOTIMPL(_T("IOleLinkImpl::SetSourceDisplayName"));
  2831.     }
  2832.  
  2833.     STDMETHOD(GetSourceDisplayName)(LPOLESTR *ppszDisplayName)
  2834.     {
  2835.         ATLTRACE2(atlTraceControls,2,_T("IOleLink::GetSourceDisplayName\n"));
  2836.         *ppszDisplayName = NULL;
  2837.         return E_FAIL;
  2838.     }
  2839.  
  2840.     STDMETHOD(BindToSource)(DWORD /* bindflags */, IBindCtx* /* pbc */)
  2841.     {
  2842.         ATLTRACENOTIMPL(_T("IOleLinkImpl::BindToSource\n"));
  2843.     };
  2844.  
  2845.     STDMETHOD(BindIfRunning)()
  2846.     {
  2847.         ATLTRACE2(atlTraceControls,2,_T("IOleLinkImpl::BindIfRunning\n"));
  2848.         return S_OK;
  2849.     };
  2850.  
  2851.     STDMETHOD(GetBoundSource)(IUnknown** /* ppunk */)
  2852.     {
  2853.         ATLTRACENOTIMPL(_T("IOleLinkImpl::GetBoundSource"));
  2854.     };
  2855.  
  2856.     STDMETHOD(UnbindSource)()
  2857.     {
  2858.         ATLTRACENOTIMPL(_T("IOleLinkImpl::UnbindSource"));
  2859.     };
  2860.  
  2861.     STDMETHOD(Update)(IBindCtx* /* pbc */)
  2862.     {
  2863.         ATLTRACENOTIMPL(_T("IOleLinkImpl::Update"));
  2864.     };
  2865. };
  2866.  
  2867. template <class T>
  2868. class ATL_NO_VTABLE CBindStatusCallback :
  2869.     public CComObjectRootEx<T::_ThreadModel::ThreadModelNoCS>,
  2870.     public IBindStatusCallback
  2871. {
  2872.     typedef void (T::*ATL_PDATAAVAILABLE)(CBindStatusCallback<T>* pbsc, BYTE* pBytes, DWORD dwSize);
  2873.  
  2874. public:
  2875.  
  2876. BEGIN_COM_MAP(CBindStatusCallback<T>)
  2877.     COM_INTERFACE_ENTRY(IBindStatusCallback)
  2878. END_COM_MAP()
  2879.  
  2880.     CBindStatusCallback()
  2881.     {
  2882.         m_pT = NULL;
  2883.         m_pFunc = NULL;
  2884.     }
  2885.     ~CBindStatusCallback()
  2886.     {
  2887.         ATLTRACE2(atlTraceControls,2,_T("~CBindStatusCallback\n"));
  2888.     }
  2889.  
  2890.     STDMETHOD(OnStartBinding)(DWORD dwReserved, IBinding *pBinding)
  2891.     {
  2892.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnStartBinding\n"));
  2893.         m_spBinding = pBinding;
  2894.         return S_OK;
  2895.     }
  2896.  
  2897.     STDMETHOD(GetPriority)(LONG *pnPriority)
  2898.     {
  2899.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::GetPriority"));
  2900.         HRESULT hr = S_OK;
  2901.         if (pnPriority)
  2902.             *pnPriority = THREAD_PRIORITY_NORMAL;
  2903.         else
  2904.             hr = E_INVALIDARG;
  2905.         return S_OK;
  2906.     }
  2907.  
  2908.     STDMETHOD(OnLowResource)(DWORD reserved)
  2909.     {
  2910.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnLowResource"));
  2911.         return S_OK;
  2912.     }
  2913.  
  2914.     STDMETHOD(OnProgress)(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
  2915.     {
  2916.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnProgress"));
  2917.         return S_OK;
  2918.     }
  2919.  
  2920.     STDMETHOD(OnStopBinding)(HRESULT hresult, LPCWSTR szError)
  2921.     {
  2922.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnStopBinding\n"));
  2923.         (m_pT->*m_pFunc)(this, NULL, 0);
  2924.         m_spBinding.Release();
  2925.         m_spBindCtx.Release();
  2926.         m_spMoniker.Release();
  2927.         return S_OK;
  2928.     }
  2929.  
  2930.     STDMETHOD(GetBindInfo)(DWORD *pgrfBINDF, BINDINFO *pbindInfo)
  2931.     {
  2932.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::GetBindInfo\n"));
  2933.  
  2934.         if (pbindInfo==NULL || pbindInfo->cbSize==0 || pgrfBINDF==NULL)
  2935.             return E_INVALIDARG;
  2936.  
  2937.         *pgrfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE |
  2938.             BINDF_GETNEWESTVERSION | BINDF_NOWRITECACHE;
  2939.  
  2940.         ULONG cbSize = pbindInfo->cbSize;        // remember incoming cbSize
  2941.         memset(pbindInfo, 0, cbSize);            // zero out structure
  2942.         pbindInfo->cbSize = cbSize;                // restore cbSize
  2943.         pbindInfo->dwBindVerb = BINDVERB_GET;    // set verb
  2944.         return S_OK;
  2945.     }
  2946.  
  2947.     STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
  2948.     {
  2949.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnDataAvailable\n"));
  2950.         HRESULT hr = S_OK;
  2951.  
  2952.         // Get the Stream passed
  2953.         if (BSCF_FIRSTDATANOTIFICATION & grfBSCF)
  2954.         {
  2955.             if (!m_spStream && pstgmed->tymed == TYMED_ISTREAM)
  2956.                 m_spStream = pstgmed->pstm;
  2957.         }
  2958.  
  2959.         DWORD dwRead = dwSize - m_dwTotalRead; // Minimum amount available that hasn't been read
  2960.         DWORD dwActuallyRead = 0;            // Placeholder for amount read during this pull
  2961.  
  2962.         // If there is some data to be read then go ahead and read them
  2963.         if (m_spStream)
  2964.         {
  2965.             if (dwRead > 0)
  2966.             {
  2967.                 BYTE* pBytes = NULL;
  2968.                 ATLTRY(pBytes = new BYTE[dwRead + 1]);
  2969.                 if (pBytes == NULL)
  2970.                     return E_OUTOFMEMORY;
  2971.                 hr = m_spStream->Read(pBytes, dwRead, &dwActuallyRead);
  2972.                 if (SUCCEEDED(hr))
  2973.                 {
  2974.                     pBytes[dwActuallyRead] = 0;
  2975.                     if (dwActuallyRead>0)
  2976.                     {
  2977.                         (m_pT->*m_pFunc)(this, pBytes, dwActuallyRead);
  2978.                         m_dwTotalRead += dwActuallyRead;
  2979.                     }
  2980.                 }
  2981.                 delete[] pBytes;
  2982.             }
  2983.         }
  2984.  
  2985.         if (BSCF_LASTDATANOTIFICATION & grfBSCF)
  2986.             m_spStream.Release();
  2987.         return hr;
  2988.     }
  2989.  
  2990.     STDMETHOD(OnObjectAvailable)(REFIID riid, IUnknown *punk)
  2991.     {
  2992.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnObjectAvailable"));
  2993.         return S_OK;
  2994.     }
  2995.  
  2996.     HRESULT _StartAsyncDownload(BSTR bstrURL, IUnknown* pUnkContainer, BOOL bRelative)
  2997.     {
  2998.         m_dwTotalRead = 0;
  2999.         m_dwAvailableToRead = 0;
  3000.         HRESULT hr = S_OK;
  3001.         CComQIPtr<IServiceProvider, &IID_IServiceProvider> spServiceProvider(pUnkContainer);
  3002.         CComPtr<IBindHost>    spBindHost;
  3003.         CComPtr<IStream>    spStream;
  3004.         if (spServiceProvider)
  3005.             spServiceProvider->QueryService(SID_IBindHost, IID_IBindHost, (void**)&spBindHost);
  3006.  
  3007.         if (spBindHost == NULL)
  3008.         {
  3009.             if (bRelative)
  3010.                 return E_NOINTERFACE;  // relative asked for, but no IBindHost
  3011.             hr = CreateURLMoniker(NULL, bstrURL, &m_spMoniker);
  3012.             if (SUCCEEDED(hr))
  3013.                 hr = CreateBindCtx(0, &m_spBindCtx);
  3014.  
  3015.             if (SUCCEEDED(hr))
  3016.                 hr = RegisterBindStatusCallback(m_spBindCtx, static_cast<IBindStatusCallback*>(this), 0, 0L);
  3017.             else
  3018.                 m_spMoniker.Release();
  3019.  
  3020.             if (SUCCEEDED(hr))
  3021.                 hr = m_spMoniker->BindToStorage(m_spBindCtx, 0, IID_IStream, (void**)&spStream);
  3022.         }
  3023.         else
  3024.         {
  3025.             hr = CreateBindCtx(0, &m_spBindCtx);
  3026.             if (SUCCEEDED(hr))
  3027.                 hr = RegisterBindStatusCallback(m_spBindCtx, static_cast<IBindStatusCallback*>(this), 0, 0L);
  3028.  
  3029.             if (SUCCEEDED(hr))
  3030.             {
  3031.                 if (bRelative)
  3032.                     hr = spBindHost->CreateMoniker(bstrURL, m_spBindCtx, &m_spMoniker, 0);
  3033.                 else
  3034.                     hr = CreateURLMoniker(NULL, bstrURL, &m_spMoniker);
  3035.             }
  3036.  
  3037.             if (SUCCEEDED(hr))
  3038.             {
  3039.                 hr = spBindHost->MonikerBindToStorage(m_spMoniker, m_spBindCtx, static_cast<IBindStatusCallback*>(this), IID_IStream, (void**)&spStream);
  3040.                 ATLTRACE2(atlTraceControls,2,_T("Bound"));
  3041.             }
  3042.         }
  3043.         return hr;
  3044.     }
  3045.  
  3046.     HRESULT StartAsyncDownload(T* pT, ATL_PDATAAVAILABLE pFunc, BSTR bstrURL, IUnknown* pUnkContainer = NULL, BOOL bRelative = FALSE)
  3047.     {
  3048.         m_pT = pT;
  3049.         m_pFunc = pFunc;
  3050.         return  _StartAsyncDownload(bstrURL, pUnkContainer, bRelative);
  3051.     }
  3052.  
  3053.     static HRESULT Download(T* pT, ATL_PDATAAVAILABLE pFunc, BSTR bstrURL, IUnknown* pUnkContainer = NULL, BOOL bRelative = FALSE)
  3054.     {
  3055.         CComObject<CBindStatusCallback<T> > *pbsc;
  3056.         HRESULT hRes = CComObject<CBindStatusCallback<T> >::CreateInstance(&pbsc);
  3057.         if (FAILED(hRes))
  3058.             return hRes;
  3059.         return pbsc->StartAsyncDownload(pT, pFunc, bstrURL, pUnkContainer, bRelative);
  3060.     }
  3061.  
  3062.     CComPtr<IMoniker> m_spMoniker;
  3063.     CComPtr<IBindCtx> m_spBindCtx;
  3064.     CComPtr<IBinding> m_spBinding;
  3065.     CComPtr<IStream> m_spStream;
  3066.     T* m_pT;
  3067.     ATL_PDATAAVAILABLE m_pFunc;
  3068.     DWORD m_dwTotalRead;
  3069.     DWORD m_dwAvailableToRead;
  3070. };
  3071.  
  3072. #define IMPLEMENT_STOCKPROP(type, fname, pname, dispid) \
  3073.     HRESULT STDMETHODCALLTYPE put_##fname(type pname) \
  3074.     { \
  3075.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_%s\n"), #fname); \
  3076.         T* pT = (T*) this; \
  3077.         if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  3078.             return S_FALSE; \
  3079.         pT->m_##pname = pname; \
  3080.         pT->m_bRequiresSave = TRUE; \
  3081.         pT->FireOnChanged(dispid); \
  3082.         pT->FireViewChange(); \
  3083.         pT->SendOnDataChange(NULL); \
  3084.         return S_OK; \
  3085.     } \
  3086.     HRESULT STDMETHODCALLTYPE get_##fname(type* p##pname) \
  3087.     { \
  3088.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_%s\n"), #fname); \
  3089.         T* pT = (T*) this; \
  3090.         *p##pname = pT->m_##pname; \
  3091.         return S_OK; \
  3092.     }
  3093.  
  3094. #define IMPLEMENT_BOOL_STOCKPROP(fname, pname, dispid) \
  3095.     HRESULT STDMETHODCALLTYPE put_##fname(VARIANT_BOOL pname) \
  3096.     { \
  3097.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_%s\n"), #fname); \
  3098.         T* pT = (T*) this; \
  3099.         if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  3100.             return S_FALSE; \
  3101.         pT->m_##pname = pname; \
  3102.         pT->m_bRequiresSave = TRUE; \
  3103.         pT->FireOnChanged(dispid); \
  3104.         pT->FireViewChange(); \
  3105.         pT->SendOnDataChange(NULL); \
  3106.         return S_OK; \
  3107.     } \
  3108.     HRESULT STDMETHODCALLTYPE get_##fname(VARIANT_BOOL* p##pname) \
  3109.     { \
  3110.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_%s\n"), #fname); \
  3111.         T* pT = (T*) this; \
  3112.         *p##pname = pT->m_##pname ? VARIANT_TRUE : VARIANT_FALSE; \
  3113.         return S_OK; \
  3114.     }
  3115.  
  3116. #define IMPLEMENT_BSTR_STOCKPROP(fname, pname, dispid) \
  3117.     HRESULT STDMETHODCALLTYPE put_##fname(BSTR pname) \
  3118.     { \
  3119.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_%s\n"), #fname); \
  3120.         T* pT = (T*) this; \
  3121.         if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  3122.             return S_FALSE; \
  3123.         if (*(&(pT->m_##pname)) != NULL) \
  3124.             SysFreeString(*(&(pT->m_##pname))); \
  3125.         *(&(pT->m_##pname)) = SysAllocString(pname); \
  3126.         pT->m_bRequiresSave = TRUE; \
  3127.         pT->FireOnChanged(dispid); \
  3128.         pT->FireViewChange(); \
  3129.         pT->SendOnDataChange(NULL); \
  3130.         return S_OK; \
  3131.     } \
  3132.     HRESULT STDMETHODCALLTYPE get_##fname(BSTR* p##pname) \
  3133.     { \
  3134.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_%s\n"), #fname); \
  3135.         T* pT = (T*) this; \
  3136.         *p##pname = SysAllocString(pT->m_##pname); \
  3137.         return S_OK; \
  3138.     }
  3139.  
  3140.  
  3141. template < class T, class InterfaceName, const IID* piid, const GUID* plibid>
  3142. class ATL_NO_VTABLE CStockPropImpl : public IDispatchImpl< InterfaceName, piid, plibid >
  3143. {
  3144. public:
  3145.     // Font
  3146.     HRESULT STDMETHODCALLTYPE put_Font(IFontDisp* pFont)
  3147.     {
  3148.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_Font\n"));
  3149.         T* pT = (T*) this;
  3150.         if (pT->FireOnRequestEdit(DISPID_FONT) == S_FALSE)
  3151.             return S_FALSE;
  3152.         pT->m_pFont = 0;
  3153.         if (pFont)
  3154.         {
  3155.             CComQIPtr<IFont, &IID_IFont> p(pFont);
  3156.             if (p)
  3157.             {
  3158.                 CComPtr<IFont> pFont;
  3159.                 p->Clone(&pFont);
  3160.                 if (pFont)
  3161.                     pFont->QueryInterface(IID_IFontDisp, (void**) &pT->m_pFont);
  3162.             }
  3163.         }
  3164.         pT->m_bRequiresSave = TRUE;
  3165.         pT->FireOnChanged(DISPID_FONT);
  3166.         pT->FireViewChange();
  3167.         pT->SendOnDataChange(NULL);
  3168.         return S_OK;
  3169.     }
  3170.     HRESULT STDMETHODCALLTYPE putref_Font(IFontDisp* pFont)
  3171.     {
  3172.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::putref_Font\n"));
  3173.         T* pT = (T*) this;
  3174.         if (pT->FireOnRequestEdit(DISPID_FONT) == S_FALSE)
  3175.             return S_FALSE;
  3176.         pT->m_pFont = pFont;
  3177.         pT->m_bRequiresSave = TRUE;
  3178.         pT->FireOnChanged(DISPID_FONT);
  3179.         pT->FireViewChange();
  3180.         pT->SendOnDataChange(NULL);
  3181.         return S_OK;
  3182.     }
  3183.     HRESULT STDMETHODCALLTYPE get_Font(IFontDisp** ppFont)
  3184.     {
  3185.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_Font\n"));
  3186.         T* pT = (T*) this;
  3187.         *ppFont = pT->m_pFont;
  3188.         if (*ppFont != NULL)
  3189.             (*ppFont)->AddRef();
  3190.         return S_OK;
  3191.     }
  3192.     // Picture
  3193.     HRESULT STDMETHODCALLTYPE put_Picture(IPictureDisp* pPicture)
  3194.     {
  3195.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_Picture\n"));
  3196.         T* pT = (T*) this;
  3197.         if (pT->FireOnRequestEdit(DISPID_PICTURE) == S_FALSE)
  3198.             return S_FALSE;
  3199.         pT->m_pPicture = 0;
  3200.         if (pPicture)
  3201.         {
  3202.             CComQIPtr<IPersistStream, &IID_IPersistStream> p(pPicture);
  3203.             if (p)
  3204.             {
  3205.                 ULARGE_INTEGER l;
  3206.                 p->GetSizeMax(&l);
  3207.                 HGLOBAL hGlob = GlobalAlloc(GHND, l.LowPart);
  3208.                 if (hGlob)
  3209.                 {
  3210.                     CComPtr<IStream> spStream;
  3211.                     CreateStreamOnHGlobal(hGlob, TRUE, &spStream);
  3212.                     if (spStream)
  3213.                     {
  3214.                         if (SUCCEEDED(p->Save(spStream, FALSE)))
  3215.                         {
  3216.                             LARGE_INTEGER l;
  3217.                             l.QuadPart = 0;
  3218.                             spStream->Seek(l, STREAM_SEEK_SET, NULL);
  3219.                             OleLoadPicture(spStream, l.LowPart, FALSE, IID_IPictureDisp, (void**)&pT->m_pPicture);
  3220.                         }
  3221.                         spStream.Release();
  3222.                     }
  3223.                     GlobalFree(hGlob);
  3224.                 }
  3225.             }
  3226.         }
  3227.         pT->m_bRequiresSave = TRUE;
  3228.         pT->FireOnChanged(DISPID_PICTURE);
  3229.         pT->FireViewChange();
  3230.         pT->SendOnDataChange(NULL);
  3231.         return S_OK;
  3232.     }
  3233.     HRESULT STDMETHODCALLTYPE putref_Picture(IPictureDisp* pPicture)
  3234.     {
  3235.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::putref_Picture\n"));
  3236.         T* pT = (T*) this;
  3237.         if (pT->FireOnRequestEdit(DISPID_PICTURE) == S_FALSE)
  3238.             return S_FALSE;
  3239.         pT->m_pPicture = pPicture;
  3240.         pT->m_bRequiresSave = TRUE;
  3241.         pT->FireOnChanged(DISPID_PICTURE);
  3242.         pT->FireViewChange();
  3243.         pT->SendOnDataChange(NULL);
  3244.         return S_OK;
  3245.     }
  3246.     HRESULT STDMETHODCALLTYPE get_Picture(IPictureDisp** ppPicture)
  3247.     {
  3248.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_Picture\n"));
  3249.         T* pT = (T*) this;
  3250.         *ppPicture = pT->m_pPicture;
  3251.         if (*ppPicture != NULL)
  3252.             (*ppPicture)->AddRef();
  3253.         return S_OK;
  3254.     }
  3255.     // MouseIcon
  3256.     HRESULT STDMETHODCALLTYPE put_MouseIcon(IPictureDisp* pPicture)
  3257.     {
  3258.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_MouseIcon\n"));
  3259.         T* pT = (T*) this;
  3260.         if (pT->FireOnRequestEdit(DISPID_MOUSEICON) == S_FALSE)
  3261.             return S_FALSE;
  3262.         pT->m_pMouseIcon = 0;
  3263.         if (pPicture)
  3264.         {
  3265.             CComQIPtr<IPersistStream, &IID_IPersistStream> p(pPicture);
  3266.             if (p)
  3267.             {
  3268.                 ULARGE_INTEGER l;
  3269.                 p->GetSizeMax(&l);
  3270.                 HGLOBAL hGlob = GlobalAlloc(GHND, l.LowPart);
  3271.                 if (hGlob)
  3272.                 {
  3273.                     CComPtr<IStream> spStream;
  3274.                     CreateStreamOnHGlobal(hGlob, TRUE, &spStream);
  3275.                     if (spStream)
  3276.                     {
  3277.                         if (SUCCEEDED(p->Save(spStream, FALSE)))
  3278.                         {
  3279.                             LARGE_INTEGER l;
  3280.                             l.QuadPart = 0;
  3281.                             spStream->Seek(l, STREAM_SEEK_SET, NULL);
  3282.                             OleLoadPicture(spStream, l.LowPart, FALSE, IID_IPictureDisp, (void**)&pT->m_pMouseIcon);
  3283.                         }
  3284.                         spStream.Release();
  3285.                     }
  3286.                     GlobalFree(hGlob);
  3287.                 }
  3288.             }
  3289.         }
  3290.         pT->m_bRequiresSave = TRUE;
  3291.         pT->FireOnChanged(DISPID_MOUSEICON);
  3292.         pT->FireViewChange();
  3293.         pT->SendOnDataChange(NULL);
  3294.         return S_OK;
  3295.     }
  3296.     HRESULT STDMETHODCALLTYPE putref_MouseIcon(IPictureDisp* pPicture)
  3297.     {
  3298.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::putref_MouseIcon\n"));
  3299.         T* pT = (T*) this;
  3300.         if (pT->FireOnRequestEdit(DISPID_MOUSEICON) == S_FALSE)
  3301.             return S_FALSE;
  3302.         pT->m_pMouseIcon = pPicture;
  3303.         pT->m_bRequiresSave = TRUE;
  3304.         pT->FireOnChanged(DISPID_MOUSEICON);
  3305.         pT->FireViewChange();
  3306.         pT->SendOnDataChange(NULL);
  3307.         return S_OK;
  3308.     }
  3309.     HRESULT STDMETHODCALLTYPE get_MouseIcon(IPictureDisp** ppPicture)
  3310.     {
  3311.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_MouseIcon\n"));
  3312.         T* pT = (T*) this;
  3313.         *ppPicture = pT->m_pMouseIcon;
  3314.         if (*ppPicture != NULL)
  3315.             (*ppPicture)->AddRef();
  3316.         return S_OK;
  3317.     }
  3318.     IMPLEMENT_STOCKPROP(OLE_COLOR, BackColor, clrBackColor, DISPID_BACKCOLOR)
  3319.     IMPLEMENT_STOCKPROP(OLE_COLOR, BorderColor, clrBorderColor, DISPID_BORDERCOLOR)
  3320.     IMPLEMENT_STOCKPROP(OLE_COLOR, FillColor, clrFillColor, DISPID_FILLCOLOR)
  3321.     IMPLEMENT_STOCKPROP(OLE_COLOR, ForeColor, clrForeColor, DISPID_FORECOLOR)
  3322.     IMPLEMENT_BOOL_STOCKPROP(AutoSize, bAutoSize, DISPID_AUTOSIZE)
  3323.     IMPLEMENT_BOOL_STOCKPROP(Valid, bValid, DISPID_VALID)
  3324.     IMPLEMENT_BOOL_STOCKPROP(Enabled, bEnabled, DISPID_ENABLED)
  3325.     IMPLEMENT_BOOL_STOCKPROP(TabStop, bTabStop, DISPID_TABSTOP)
  3326.     IMPLEMENT_BOOL_STOCKPROP(BorderVisible, bBorderVisible, DISPID_BORDERVISIBLE)
  3327.     IMPLEMENT_BSTR_STOCKPROP(Text, bstrText, DISPID_TEXT)
  3328.     IMPLEMENT_BSTR_STOCKPROP(Caption, bstrCaption, DISPID_CAPTION)
  3329.     HRESULT STDMETHODCALLTYPE put_Window(long /*hWnd*/)
  3330.     {
  3331.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_Window\n"));
  3332.         return E_FAIL;
  3333.     }
  3334.     HRESULT STDMETHODCALLTYPE get_Window(long* phWnd)
  3335.     {
  3336.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_Window\n"));
  3337.         T* pT = (T*) this;
  3338.         *phWnd = (long)pT->m_hWnd;
  3339.         return S_OK;
  3340.     }
  3341.     IMPLEMENT_STOCKPROP(LONG, BackStyle, nBackStyle, DISPID_BACKSTYLE)
  3342.     IMPLEMENT_STOCKPROP(LONG, BorderStyle, nBorderStyle, DISPID_BORDERSTYLE)
  3343.     IMPLEMENT_STOCKPROP(LONG, BorderWidth, nBorderWidth, DISPID_BORDERWIDTH)
  3344.     IMPLEMENT_STOCKPROP(LONG, DrawMode, nDrawMode, DISPID_DRAWMODE)
  3345.     IMPLEMENT_STOCKPROP(LONG, DrawStyle, nDrawStyle, DISPID_DRAWSTYLE)
  3346.     IMPLEMENT_STOCKPROP(LONG, DrawWidth, nDrawWidth, DISPID_DRAWWIDTH)
  3347.     IMPLEMENT_STOCKPROP(LONG, FillStyle, nFillStyle, DISPID_FILLSTYLE)
  3348.     IMPLEMENT_STOCKPROP(SHORT, Appearance, nAppearance, DISPID_APPEARANCE)
  3349.     IMPLEMENT_STOCKPROP(LONG, MousePointer, nMousePointer, DISPID_MOUSEPOINTER)
  3350.     IMPLEMENT_STOCKPROP(LONG, ReadyState, nReadyState, DISPID_READYSTATE)
  3351. };
  3352.  
  3353. #pragma pack(pop)
  3354.  
  3355. }; //namespace ATL
  3356.  
  3357. #ifndef _ATL_DLL_IMPL
  3358. #ifndef _ATL_DLL
  3359. #define _ATLCTL_IMPL
  3360. #endif
  3361. #endif
  3362.  
  3363. #endif // __ATLCTL_H__
  3364.  
  3365. #ifdef _ATLCTL_IMPL
  3366.  
  3367. #ifndef _ATL_DLL_IMPL
  3368. namespace ATL
  3369. {
  3370. #endif
  3371.  
  3372.  
  3373. //All exports go here
  3374.  
  3375.  
  3376. #ifndef _ATL_DLL_IMPL
  3377. }; //namespace ATL
  3378. #endif
  3379.  
  3380. //Prevent pulling in second time 
  3381. #undef _ATLCTL_IMPL
  3382.  
  3383. #endif // _ATLCTL_IMPL
  3384.  
  3385.