Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2721 lines
74 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1997 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. #ifndef __ATLCTL_H__
  11. #define __ATLCTL_H__
  12. #ifndef __cplusplus
  13. #error ATL requires C++ compilation (use a .cpp suffix)
  14. #endif
  15. #include <atlwin.h>
  16. #include <objsafe.h>
  17. #include <urlmon.h>
  18. #pragma comment(lib, "gdi32.lib")
  19. #pragma comment(lib, "urlmon.lib")
  20. ATLAPI_(void) AtlHiMetricToPixel(const SIZEL * lpSizeInHiMetric, LPSIZEL lpSizeInPix);
  21. ATLAPI_(void) AtlPixelToHiMetric(const SIZEL * lpSizeInPix, LPSIZEL lpSizeInHiMetric);
  22. ATLAPI_(HDC) AtlCreateTargetDC(HDC hdc, DVTARGETDEVICE* ptd);
  23. // Include GUIDs for the new stock property dialogs contained in the dll MSStkProp.DLL
  24. #include "msstkppg.h"
  25. #define CLSID_MSStockFont CLSID_StockFontPage
  26. #define CLSID_MSStockColor CLSID_StockColorPage
  27. #define CLSID_MSStockPicture CLSID_StockPicturePage
  28. #ifndef ATL_NO_NAMESPACE
  29. namespace ATL
  30. {
  31. #endif
  32. #pragma pack(push, _ATL_PACKING)
  33. // Forward declarations
  34. //
  35. class ATL_NO_VTABLE CComControlBase;
  36. template <class T> class CComControl;
  37. class CComDispatchDriver;
  38. struct ATL_PROPMAP_ENTRY
  39. {
  40. LPCOLESTR szDesc;
  41. DISPID dispid;
  42. const CLSID* pclsidPropPage;
  43. const IID* piidDispatch;
  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. // CComDispatchDriver / Specialization of CComQIPtr<IDispatch, IID_IDispatch>
  63. class CComDispatchDriver
  64. {
  65. public:
  66. CComDispatchDriver()
  67. {
  68. p = NULL;
  69. }
  70. CComDispatchDriver(IDispatch* lp)
  71. {
  72. if ((p = lp) != NULL)
  73. p->AddRef();
  74. }
  75. CComDispatchDriver(IUnknown* lp)
  76. {
  77. p=NULL;
  78. if (lp != NULL)
  79. lp->QueryInterface(IID_IDispatch, (void **)&p);
  80. }
  81. ~CComDispatchDriver() { if (p) p->Release(); }
  82. void Release() {if (p) p->Release(); p=NULL;}
  83. operator IDispatch*() {return p;}
  84. IDispatch& operator*() {_ASSERTE(p!=NULL); return *p; }
  85. IDispatch** operator&() {_ASSERTE(p==NULL); return &p; }
  86. IDispatch* operator->() {_ASSERTE(p!=NULL); return p; }
  87. IDispatch* operator=(IDispatch* lp){return (IDispatch*)AtlComPtrAssign((IUnknown**)&p, lp);}
  88. IDispatch* operator=(IUnknown* lp)
  89. {
  90. return (IDispatch*)AtlComQIPtrAssign((IUnknown**)&p, lp, IID_IDispatch);
  91. }
  92. BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
  93. HRESULT GetProperty(DISPID dwDispID, VARIANT* pVar)
  94. {
  95. _ASSERTE(p);
  96. return GetProperty(p, dwDispID, pVar);
  97. }
  98. HRESULT PutProperty(DISPID dwDispID, VARIANT* pVar)
  99. {
  100. _ASSERTE(p);
  101. return PutProperty(p, dwDispID, pVar);
  102. }
  103. static HRESULT GetProperty(IDispatch* pDisp, DISPID dwDispID, VARIANT* pVar);
  104. static HRESULT PutProperty(IDispatch* pDisp, DISPID dwDispID, VARIANT* pVar);
  105. IDispatch* p;
  106. };
  107. //////////////////////////////////////////////////////////////////////////////
  108. // CFirePropNotifyEvent
  109. class CFirePropNotifyEvent
  110. {
  111. public:
  112. static HRESULT FireOnRequestEdit(IUnknown* pUnk, DISPID dispID);
  113. static HRESULT FireOnChanged(IUnknown* pUnk, DISPID dispID);
  114. };
  115. //////////////////////////////////////////////////////////////////////////////
  116. // CFakeFirePropNotifyEvent
  117. class CFakeFirePropNotifyEvent
  118. {
  119. public:
  120. static HRESULT FireOnRequestEdit(IUnknown* /*pUnk*/, DISPID /*dispID*/)
  121. {
  122. return S_OK;
  123. }
  124. static HRESULT FireOnChanged(IUnknown* /*pUnk*/, DISPID /*dispID*/)
  125. {
  126. return S_OK;
  127. }
  128. };
  129. typedef CFakeFirePropNotifyEvent _ATL_PROP_NOTIFY_EVENT_CLASS;
  130. //////////////////////////////////////////////////////////////////////////////
  131. // CComControl
  132. class ATL_NO_VTABLE CComControlBase
  133. {
  134. public:
  135. CComControlBase(HWND& h) : m_hWndCD(h)
  136. {
  137. memset(this, 0, sizeof(CComControlBase));
  138. m_phWndCD = &h;
  139. m_sizeExtent.cx = 2*2540;
  140. m_sizeExtent.cy = 2*2540;
  141. m_sizeNatural = m_sizeExtent;
  142. }
  143. ~CComControlBase()
  144. {
  145. if (m_hWndCD != NULL)
  146. ::DestroyWindow(m_hWndCD);
  147. ATLTRACE(_T("Control Destroyed\n"));
  148. }
  149. // methods
  150. public:
  151. // Control helper functions can go here
  152. // non-virtuals only please
  153. void SetDirty(BOOL bDirty)
  154. {
  155. m_bRequiresSave = bDirty;
  156. }
  157. BOOL GetDirty()
  158. {
  159. return m_bRequiresSave ? TRUE : FALSE;
  160. }
  161. void GetZoomInfo(ATL_DRAWINFO& di);
  162. HRESULT SendOnRename(IMoniker *pmk)
  163. {
  164. HRESULT hRes = S_OK;
  165. if (m_spOleAdviseHolder)
  166. hRes = m_spOleAdviseHolder->SendOnRename(pmk);
  167. return hRes;
  168. }
  169. HRESULT SendOnSave()
  170. {
  171. HRESULT hRes = S_OK;
  172. if (m_spOleAdviseHolder)
  173. hRes = m_spOleAdviseHolder->SendOnSave();
  174. return hRes;
  175. }
  176. HRESULT SendOnClose()
  177. {
  178. HRESULT hRes = S_OK;
  179. if (m_spOleAdviseHolder)
  180. hRes = m_spOleAdviseHolder->SendOnClose();
  181. return hRes;
  182. }
  183. HRESULT SendOnDataChange(DWORD advf = 0);
  184. HRESULT SendOnViewChange(DWORD dwAspect, LONG lindex = -1)
  185. {
  186. if (m_spAdviseSink)
  187. m_spAdviseSink->OnViewChange(dwAspect, lindex);
  188. return S_OK;
  189. }
  190. LRESULT OnSetFocus(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* bHandled */)
  191. {
  192. CComQIPtr <IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  193. if (m_bInPlaceActive && spSite)
  194. spSite->OnFocus(TRUE);
  195. return 0;
  196. }
  197. LRESULT OnKillFocus(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* bHandled */)
  198. {
  199. CComQIPtr <IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  200. if (m_bInPlaceActive && spSite)
  201. spSite->OnFocus(FALSE);
  202. return 0;
  203. }
  204. LRESULT OnGetDlgCode(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* bHandled */)
  205. {
  206. return 0;
  207. }
  208. HRESULT GetAmbientProperty(DISPID dispid, VARIANT& var)
  209. {
  210. HRESULT hRes = E_FAIL;
  211. if (m_spAmbientDispatch.p != NULL)
  212. hRes = m_spAmbientDispatch.GetProperty(dispid, &var);
  213. return hRes;
  214. }
  215. HRESULT GetAmbientAppearance(short& nAppearance)
  216. {
  217. CComVariant var;
  218. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_APPEARANCE, var);
  219. _ASSERTE(var.vt == VT_I2 || FAILED(hRes));
  220. nAppearance = var.iVal;
  221. return hRes;
  222. }
  223. HRESULT GetAmbientBackColor(OLE_COLOR& BackColor)
  224. {
  225. CComVariant var;
  226. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_BACKCOLOR, var);
  227. _ASSERTE(var.vt == VT_I4 || FAILED(hRes));
  228. BackColor = var.lVal;
  229. return hRes;
  230. }
  231. HRESULT GetAmbientDisplayName(BSTR& bstrDiaplayName)
  232. {
  233. CComVariant var;
  234. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_DISPLAYNAME, var);
  235. _ASSERTE(var.vt == VT_BSTR || FAILED(hRes));
  236. bstrDiaplayName = var.bstrVal;
  237. return hRes;
  238. }
  239. HRESULT GetAmbientFont(IFont** ppFont)
  240. {
  241. // caller MUST Release the font!
  242. if (ppFont == NULL)
  243. return E_POINTER;
  244. CComVariant var;
  245. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FONT, var);
  246. _ASSERTE((var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH) || FAILED(hRes));
  247. if (SUCCEEDED(hRes) && var.pdispVal)
  248. {
  249. if (var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH)
  250. hRes = var.pdispVal->QueryInterface(IID_IFont, (void**)ppFont);
  251. else
  252. hRes = DISP_E_BADVARTYPE;
  253. }
  254. return hRes;
  255. }
  256. HRESULT GetAmbientForeColor(OLE_COLOR& ForeColor)
  257. {
  258. CComVariant var;
  259. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FORECOLOR, var);
  260. _ASSERTE(var.vt == VT_I4 || FAILED(hRes));
  261. ForeColor = var.lVal;
  262. return hRes;
  263. }
  264. HRESULT GetAmbientLocaleID(LCID& lcid)
  265. {
  266. CComVariant var;
  267. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_LOCALEID, var);
  268. _ASSERTE(var.vt == VT_I4 || FAILED(hRes));
  269. lcid = var.lVal;
  270. return hRes;
  271. }
  272. HRESULT GetAmbientScaleUnits(BSTR& bstrScaleUnits)
  273. {
  274. CComVariant var;
  275. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SCALEUNITS, var);
  276. _ASSERTE(var.vt == VT_BSTR || FAILED(hRes));
  277. bstrScaleUnits = var.bstrVal;
  278. return hRes;
  279. }
  280. HRESULT GetAmbientTextAlign(short& nTextAlign)
  281. {
  282. CComVariant var;
  283. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_TEXTALIGN, var);
  284. _ASSERTE(var.vt == VT_I2 || FAILED(hRes));
  285. nTextAlign = var.iVal;
  286. return hRes;
  287. }
  288. HRESULT GetAmbientUserMode(BOOL& bUserMode)
  289. {
  290. CComVariant var;
  291. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_USERMODE, var);
  292. _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  293. bUserMode = var.boolVal;
  294. return hRes;
  295. }
  296. HRESULT GetAmbientUIDead(BOOL& bUIDead)
  297. {
  298. CComVariant var;
  299. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_UIDEAD, var);
  300. _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  301. bUIDead = var.boolVal;
  302. return hRes;
  303. }
  304. HRESULT GetAmbientShowGrabHandles(BOOL& bShowGrabHandles)
  305. {
  306. CComVariant var;
  307. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SHOWGRABHANDLES, var);
  308. _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  309. bShowGrabHandles = var.boolVal;
  310. return hRes;
  311. }
  312. HRESULT GetAmbientShowHatching(BOOL& bShowHatching)
  313. {
  314. CComVariant var;
  315. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SHOWHATCHING, var);
  316. _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  317. bShowHatching = var.boolVal;
  318. return hRes;
  319. }
  320. HRESULT GetAmbientMessageReflect(BOOL& bMessageReflect)
  321. {
  322. CComVariant var;
  323. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_MESSAGEREFLECT, var);
  324. _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  325. bMessageReflect = var.boolVal;
  326. return hRes;
  327. }
  328. HRESULT GetAmbientAutoClip(BOOL& bAutoClip)
  329. {
  330. CComVariant var;
  331. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_AUTOCLIP, var);
  332. _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  333. bAutoClip = var.boolVal;
  334. return hRes;
  335. }
  336. HRESULT GetAmbientDisplayAsDefault(BOOL& bDisplaysDefault)
  337. {
  338. CComVariant var;
  339. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_DISPLAYASDEFAULT, var);
  340. _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  341. bDisplaysDefault = var.boolVal;
  342. return hRes;
  343. }
  344. HRESULT GetAmbientSupportsMnemonics(BOOL& bSupportMnemonics)
  345. {
  346. CComVariant var;
  347. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SUPPORTSMNEMONICS, var);
  348. _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  349. bSupportMnemonics = var.boolVal;
  350. return hRes;
  351. }
  352. HRESULT GetAmbientPalette(HPALETTE& hPalette)
  353. {
  354. CComVariant var;
  355. HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_PALETTE, var);
  356. _ASSERTE(var.vt == VT_INT_PTR || FAILED(hRes));
  357. hPalette = reinterpret_cast<HPALETTE>(var.byref);
  358. return hRes;
  359. }
  360. BOOL DoesVerbUIActivate(LONG iVerb)
  361. {
  362. BOOL b = FALSE;
  363. switch (iVerb)
  364. {
  365. case OLEIVERB_UIACTIVATE:
  366. case OLEIVERB_PRIMARY:
  367. b = TRUE;
  368. break;
  369. }
  370. // if no ambient dispatch then in old style OLE container
  371. if (DoesVerbActivate(iVerb) && m_spAmbientDispatch.p == NULL)
  372. b = TRUE;
  373. return b;
  374. }
  375. BOOL DoesVerbActivate(LONG iVerb)
  376. {
  377. BOOL b = FALSE;
  378. switch (iVerb)
  379. {
  380. case OLEIVERB_UIACTIVATE:
  381. case OLEIVERB_PRIMARY:
  382. case OLEIVERB_SHOW:
  383. case OLEIVERB_INPLACEACTIVATE:
  384. b = TRUE;
  385. break;
  386. }
  387. return b;
  388. }
  389. BOOL SetControlFocus(BOOL bGrab);
  390. HRESULT IQuickActivate_QuickActivate(QACONTAINER *pQACont,
  391. QACONTROL *pQACtrl);
  392. HRESULT IPersistPropertyBag_Load(LPPROPERTYBAG pPropBag,
  393. LPERRORLOG pErrorLog, ATL_PROPMAP_ENTRY* pMap);
  394. HRESULT IPersistPropertyBag_Save(LPPROPERTYBAG pPropBag,
  395. BOOL fClearDirty, BOOL fSaveAllProperties, ATL_PROPMAP_ENTRY* pMap);
  396. HRESULT ISpecifyPropertyPages_GetPages(CAUUID* pPages,
  397. ATL_PROPMAP_ENTRY* pMap);
  398. HRESULT DoVerbProperties(LPCRECT /* prcPosRect */, HWND hwndParent);
  399. HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect = NULL);
  400. HRESULT IPersistStreamInit_Load(LPSTREAM pStm, ATL_PROPMAP_ENTRY* pMap);
  401. HRESULT IPersistStreamInit_Save(LPSTREAM pStm, BOOL /* fClearDirty */,
  402. ATL_PROPMAP_ENTRY* pMap);
  403. HRESULT IOleObject_SetClientSite(IOleClientSite *pClientSite);
  404. HRESULT IOleObject_GetClientSite(IOleClientSite **ppClientSite);
  405. HRESULT IOleObject_Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection);
  406. HRESULT IOleObject_Close(DWORD dwSaveOption);
  407. HRESULT IOleObject_SetExtent(DWORD dwDrawAspect, SIZEL *psizel);
  408. HRESULT IOleInPlaceObject_InPlaceDeactivate(void);
  409. HRESULT IOleInPlaceObject_UIDeactivate(void);
  410. HRESULT IOleInPlaceObject_SetObjectRects(LPCRECT prcPos,LPCRECT prcClip);
  411. HRESULT IViewObject_Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect,
  412. DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw,
  413. LPCRECTL prcBounds, LPCRECTL prcWBounds);
  414. HRESULT IDataObject_GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
  415. HRESULT FireViewChange();
  416. LRESULT OnPaint(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */,
  417. BOOL& /* lResult */);
  418. virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos) = 0;
  419. virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv) = 0;
  420. virtual HRESULT OnDrawAdvanced(ATL_DRAWINFO& di);
  421. virtual HRESULT OnDraw(ATL_DRAWINFO& di)
  422. {
  423. return S_OK;
  424. }
  425. // Attributes
  426. public:
  427. CComPtr<IOleInPlaceSiteWindowless> m_spInPlaceSite;
  428. CComPtr<IDataAdviseHolder> m_spDataAdviseHolder;
  429. CComPtr<IOleAdviseHolder> m_spOleAdviseHolder;
  430. CComPtr<IOleClientSite> m_spClientSite;
  431. CComPtr<IAdviseSink> m_spAdviseSink;
  432. CComDispatchDriver m_spAmbientDispatch;
  433. SIZE m_sizeNatural; //unscaled size in himetric
  434. SIZE m_sizeExtent; //current extents in himetric
  435. RECT m_rcPos; // position in pixels
  436. union
  437. {
  438. HWND& m_hWndCD;
  439. HWND* m_phWndCD;
  440. };
  441. union
  442. {
  443. // m_nFreezeEvents is the only one actually used
  444. int m_nFreezeEvents; // count of freezes versus thaws
  445. // These are here to make stock properties work
  446. IPictureDisp* m_pMouseIcon;
  447. IPictureDisp* m_pPicture;
  448. IFontDisp* m_pFont;
  449. OLE_COLOR m_clrBackColor;
  450. OLE_COLOR m_clrBorderColor;
  451. OLE_COLOR m_clrFillColor;
  452. OLE_COLOR m_clrForeColor;
  453. BSTR m_bstrText;
  454. BSTR m_bstrCaption;
  455. BOOL m_bValid;
  456. BOOL m_bTabStop;
  457. BOOL m_bBorderVisible;
  458. BOOL m_bEnabled;
  459. long m_nBackStyle;
  460. long m_nBorderStyle;
  461. long m_nBorderWidth;
  462. long m_nDrawMode;
  463. long m_nDrawStyle;
  464. long m_nDrawWidth;
  465. long m_nFillStyle;
  466. long m_nAppearance;
  467. long m_nMousePointer;
  468. long m_nReadyState;
  469. };
  470. unsigned m_bNegotiatedWnd:1;
  471. unsigned m_bWndLess:1;
  472. unsigned m_bInPlaceActive:1;
  473. unsigned m_bUIActive:1;
  474. unsigned m_bUsingWindowRgn:1;
  475. unsigned m_bInPlaceSiteEx:1;
  476. unsigned m_bWindowOnly:1;
  477. unsigned m_bRequiresSave:1;
  478. unsigned m_bWasOnceWindowless:1;
  479. unsigned m_bAutoSize:1; //SetExtent fails if size doesn't match existing
  480. unsigned m_bRecomposeOnResize:1; //implies OLEMISC_RECOMPOSEONRESIZE
  481. unsigned m_bResizeNatural:1; //resize natural extent on SetExtent
  482. unsigned m_bDrawFromNatural:1; //instead of m_sizeExtent
  483. unsigned m_bDrawGetDataInHimetric:1; //instead of pixels
  484. };
  485. template <class T>
  486. class ATL_NO_VTABLE CComControl : public CComControlBase, public CWindowImpl<T>
  487. {
  488. public:
  489. CComControl() : CComControlBase(m_hWnd) {}
  490. HRESULT FireOnRequestEdit(DISPID dispID)
  491. {
  492. T* pT = static_cast<T*>(this);
  493. return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnRequestEdit(pT->GetUnknown(), dispID);
  494. }
  495. HRESULT FireOnChanged(DISPID dispID)
  496. {
  497. T* pT = static_cast<T*>(this);
  498. return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnChanged(pT->GetUnknown(), dispID);
  499. }
  500. virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv)
  501. {
  502. T* pT = static_cast<T*>(this);
  503. return pT->_InternalQueryInterface(iid, ppv);
  504. }
  505. virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos)
  506. {
  507. T* pT = static_cast<T*>(this);
  508. return pT->Create(hWndParent, rcPos);
  509. }
  510. };
  511. // Forward declarations
  512. //
  513. template <class T> class IPersistImpl;
  514. template <class T> class IPersistStreamInitImpl;
  515. template <class T> class IPersistStorageImpl;
  516. template <class T> class IPersistPropertyBagImpl;
  517. template <class T> class IOleControlImpl;
  518. template <class T> class IRunnableObjectImpl;
  519. template <class T> class IQuickActivateImpl;
  520. template <class T> class IOleObjectImpl;
  521. template <class T> class IPropertyPageImpl;
  522. template <class T> class IPropertyPage2Impl;
  523. template <class T> class IPerPropertyBrowsingImpl;
  524. template <class T> class IViewObjectExImpl;
  525. template <class T> class IOleWindowImpl;
  526. template <class T> class ISpecifyPropertyPagesImpl;
  527. template <class T> class IPointerInactiveImpl;
  528. template <class T, class CDV> class IPropertyNotifySinkCP;
  529. template <class T> class IBindStatusCallbackImpl;
  530. template <class T> class CBindStatusCallback;
  531. //////////////////////////////////////////////////////////////////////////////
  532. // IPersistImpl
  533. template <class T>
  534. class ATL_NO_VTABLE IPersistImpl
  535. {
  536. public:
  537. // IUnknown
  538. //
  539. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  540. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistImpl)
  541. // IPersist
  542. STDMETHOD(GetClassID)(CLSID *pClassID)
  543. {
  544. ATLTRACE(_T("IPersistImpl::GetClassID\n"));
  545. T* pT = static_cast<T*>(this);
  546. *pClassID = pT->GetObjectCLSID();
  547. return S_OK;
  548. }
  549. };
  550. #define BEGIN_PROPERTY_MAP(theClass) \
  551. typedef _ATL_PROP_NOTIFY_EVENT_CLASS __ATL_PROP_NOTIFY_EVENT_CLASS; \
  552. static ATL_PROPMAP_ENTRY* GetPropertyMap()\
  553. {\
  554. static ATL_PROPMAP_ENTRY pPropMap[] = \
  555. {
  556. #define PROP_ENTRY(szDesc, dispid, clsid) \
  557. {OLESTR(szDesc), dispid, &clsid, &IID_IDispatch},
  558. #define PROP_ENTRY_EX(szDesc, dispid, clsid, iidDispatch) \
  559. {OLESTR(szDesc), dispid, &clsid, &iidDispatch},
  560. #define PROP_PAGE(clsid) \
  561. {NULL, NULL, &clsid, &IID_NULL},
  562. #define END_PROPERTY_MAP() \
  563. {NULL, 0, NULL, &IID_NULL} \
  564. }; \
  565. return pPropMap; \
  566. }
  567. //////////////////////////////////////////////////////////////////////////////
  568. // IPersistStreamInitImpl
  569. template <class T>
  570. class ATL_NO_VTABLE IPersistStreamInitImpl
  571. {
  572. public:
  573. // IUnknown
  574. //
  575. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  576. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistStreamInitImpl)
  577. // IPersist
  578. STDMETHOD(GetClassID)(CLSID *pClassID)
  579. {
  580. ATLTRACE(_T("IPersistStreamInitImpl::GetClassID\n"));
  581. T* pT = static_cast<T*>(this);
  582. *pClassID = pT->GetObjectCLSID();
  583. return S_OK;
  584. }
  585. // IPersistStream
  586. STDMETHOD(IsDirty)()
  587. {
  588. ATLTRACE(_T("IPersistStreamInitImpl::IsDirty\n"));
  589. T* pT = static_cast<T*>(this);
  590. return (pT->m_bRequiresSave) ? S_OK : S_FALSE;
  591. }
  592. STDMETHOD(Load)(LPSTREAM pStm)
  593. {
  594. ATLTRACE(_T("IPersistStreamInitImpl::Load\n"));
  595. T* pT = static_cast<T*>(this);
  596. return pT->IPersistStreamInit_Load(pStm, T::GetPropertyMap());
  597. }
  598. STDMETHOD(Save)(LPSTREAM pStm, BOOL fClearDirty)
  599. {
  600. T* pT = static_cast<T*>(this);
  601. ATLTRACE(_T("IPersistStreamInitImpl::Save\n"));
  602. return pT->IPersistStreamInit_Save(pStm, fClearDirty, T::GetPropertyMap());
  603. }
  604. STDMETHOD(GetSizeMax)(ULARGE_INTEGER FAR* /* pcbSize */)
  605. {
  606. ATLTRACENOTIMPL(_T("IPersistStreamInitImpl::GetSizeMax"));
  607. }
  608. // IPersistStreamInit
  609. STDMETHOD(InitNew)()
  610. {
  611. T* pT = static_cast<T*>(this);
  612. ATLTRACE(_T("IPersistStreamInitImpl::InitNew\n"));
  613. pT->SendOnDataChange();
  614. return S_OK;
  615. }
  616. };
  617. //////////////////////////////////////////////////////////////////////////////
  618. // IPersistStorageImpl
  619. template <class T>
  620. class ATL_NO_VTABLE IPersistStorageImpl
  621. {
  622. public:
  623. // IUnknown
  624. //
  625. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  626. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistStorageImpl)
  627. // IPersist
  628. STDMETHOD(GetClassID)(CLSID *pClassID)
  629. {
  630. ATLTRACE(_T("IPersistStorageImpl::GetClassID\n"));
  631. T* pT = static_cast<T*>(this);
  632. *pClassID = pT->GetObjectCLSID();
  633. return S_OK;
  634. }
  635. // IPersistStorage
  636. STDMETHOD(IsDirty)(void)
  637. {
  638. ATLTRACE(_T("IPersistStorageImpl::IsDirty\n"));
  639. T* pT = static_cast<T*>(this);
  640. CComPtr<IPersistStreamInit> p;
  641. p.p = IPSI_GetIPersistStreamInit();
  642. return (p != NULL) ? p->IsDirty() : E_FAIL;
  643. }
  644. STDMETHOD(InitNew)(IStorage*)
  645. {
  646. ATLTRACE(_T("IPersistStorageImpl::InitNew\n"));
  647. T* pT = static_cast<T*>(this);
  648. CComPtr<IPersistStreamInit> p;
  649. p.p = IPSI_GetIPersistStreamInit();
  650. return (p != NULL) ? p->InitNew() : E_FAIL;
  651. }
  652. STDMETHOD(Load)(IStorage* pStorage)
  653. {
  654. ATLTRACE(_T("IPersistStorageImpl::Load\n"));
  655. T* pT = static_cast<T*>(this);
  656. CComPtr<IPersistStreamInit> p;
  657. p.p = IPSI_GetIPersistStreamInit();
  658. HRESULT hr = E_FAIL;
  659. if (p != NULL)
  660. {
  661. CComPtr<IStream> spStream;
  662. hr = pStorage->OpenStream(OLESTR("Contents"), NULL,
  663. STGM_DIRECT | STGM_SHARE_EXCLUSIVE, 0, &spStream);
  664. if (SUCCEEDED(hr))
  665. hr = p->Load(spStream);
  666. }
  667. return hr;
  668. }
  669. STDMETHOD(Save)(IStorage* pStorage, BOOL fSameAsLoad)
  670. {
  671. ATLTRACE(_T("IPersistStorageImpl::Save\n"));
  672. T* pT = static_cast<T*>(this);
  673. CComPtr<IPersistStreamInit> p;
  674. p.p = IPSI_GetIPersistStreamInit();
  675. HRESULT hr = E_FAIL;
  676. if (p != NULL)
  677. {
  678. CComPtr<IStream> spStream;
  679. static LPCOLESTR vszContents = OLESTR("Contents");
  680. hr = pStorage->CreateStream(vszContents,
  681. STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
  682. 0, 0, &spStream);
  683. if (SUCCEEDED(hr))
  684. hr = p->Save(spStream, fSameAsLoad);
  685. }
  686. return hr;
  687. }
  688. STDMETHOD(SaveCompleted)(IStorage* /* pStorage */)
  689. {
  690. ATLTRACE(_T("IPersistStorageImpl::SaveCompleted\n"));
  691. return S_OK;
  692. }
  693. STDMETHOD(HandsOffStorage)(void)
  694. {
  695. ATLTRACE(_T("IPersistStorageImpl::HandsOffStorage\n"));
  696. return S_OK;
  697. }
  698. private:
  699. IPersistStreamInit* IPSI_GetIPersistStreamInit();
  700. };
  701. template <class T>
  702. IPersistStreamInit* IPersistStorageImpl<T>::IPSI_GetIPersistStreamInit()
  703. {
  704. T* pT = static_cast<T*>(this);
  705. IPersistStreamInit* p;
  706. if (FAILED(pT->GetUnknown()->QueryInterface(IID_IPersistStreamInit, (void**)&p)))
  707. pT->_InternalQueryInterface(IID_IPersistStreamInit, (void**)&p);
  708. return p;
  709. }
  710. //////////////////////////////////////////////////////////////////////////////
  711. // IPersistPropertyBagImpl
  712. template <class T>
  713. class ATL_NO_VTABLE IPersistPropertyBagImpl
  714. {
  715. public:
  716. // IUnknown
  717. //
  718. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  719. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistPropertyBagImpl)
  720. // IPersist
  721. STDMETHOD(GetClassID)(CLSID *pClassID)
  722. {
  723. ATLTRACE(_T("IPersistPropertyBagImpl::GetClassID\n"));
  724. T* pT = static_cast<T*>(this);
  725. *pClassID = pT->GetObjectCLSID();
  726. return S_OK;
  727. }
  728. // IPersistPropertyBag
  729. //
  730. STDMETHOD(InitNew)()
  731. {
  732. ATLTRACE(_T("IPersistPropertyBagImpl::InitNew\n"));
  733. return S_OK;
  734. }
  735. STDMETHOD(Load)(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog)
  736. {
  737. ATLTRACE(_T("IPersistPropertyBagImpl::Load\n"));
  738. T* pT = static_cast<T*>(this);
  739. ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
  740. _ASSERTE(pMap != NULL);
  741. return pT->IPersistPropertyBag_Load(pPropBag, pErrorLog, pMap);
  742. }
  743. STDMETHOD(Save)(LPPROPERTYBAG pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
  744. {
  745. ATLTRACE(_T("IPersistPropertyBagImpl::Save\n"));
  746. T* pT = static_cast<T*>(this);
  747. ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
  748. _ASSERTE(pMap != NULL);
  749. return pT->IPersistPropertyBag_Save(pPropBag, fClearDirty, fSaveAllProperties, pMap);
  750. }
  751. };
  752. //////////////////////////////////////////////////////////////////////////////
  753. // IOleControlImpl
  754. template <class T>
  755. class ATL_NO_VTABLE IOleControlImpl
  756. {
  757. public:
  758. // IUnknown
  759. //
  760. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  761. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleControlImpl)
  762. // IOleControl methods
  763. //
  764. STDMETHOD(GetControlInfo)(LPCONTROLINFO /* pCI */)
  765. {
  766. ATLTRACENOTIMPL(_T("IOleControlImpl::GetControlInfo"));
  767. }
  768. STDMETHOD(OnMnemonic)(LPMSG /* pMsg */)
  769. {
  770. ATLTRACENOTIMPL(_T("IOleControlImpl::OnMnemonic"));
  771. }
  772. STDMETHOD(OnAmbientPropertyChange)(DISPID dispid)
  773. {
  774. dispid;
  775. ATLTRACE(_T("IOleControlImpl::OnAmbientPropertyChange\n"));
  776. ATLTRACE(_T(" -- DISPID = %d (%d)\n"), dispid);
  777. return S_OK;
  778. }
  779. STDMETHOD(FreezeEvents)(BOOL bFreeze)
  780. {
  781. T* pT = static_cast<T*>(this);
  782. ATLTRACE(_T("IOleControlImpl::FreezeEvents\n"));
  783. if (bFreeze)
  784. pT->m_nFreezeEvents++;
  785. else
  786. pT->m_nFreezeEvents--;
  787. return S_OK;
  788. }
  789. };
  790. //////////////////////////////////////////////////////////////////////////////
  791. // IQuickActivateImpl
  792. template <class T>
  793. class ATL_NO_VTABLE IQuickActivateImpl
  794. {
  795. public:
  796. // IUnknown
  797. //
  798. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  799. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IQuickActivateImpl)
  800. // IQuickActivate
  801. //
  802. STDMETHOD(QuickActivate)(QACONTAINER *pQACont, QACONTROL *pQACtrl)
  803. {
  804. T* pT = static_cast<T*>(this);
  805. ATLTRACE(_T("IQuickActivateImpl::QuickActivate\n"));
  806. return pT->IQuickActivate_QuickActivate(pQACont, pQACtrl);
  807. }
  808. STDMETHOD(SetContentExtent)(LPSIZEL pSize)
  809. {
  810. T* pT = static_cast<T*>(this);
  811. ATLTRACE(_T("IQuickActivateImpl::SetContentExtent\n"));
  812. return pT->IOleObjectImpl<T>::SetExtent(DVASPECT_CONTENT, pSize);
  813. }
  814. STDMETHOD(GetContentExtent)(LPSIZEL pSize)
  815. {
  816. T* pT = static_cast<T*>(this);
  817. ATLTRACE(_T("IQuickActivateImpl::GetContentExtent\n"));
  818. return pT->IOleObjectImpl<T>::GetExtent(DVASPECT_CONTENT, pSize);
  819. }
  820. };
  821. //////////////////////////////////////////////////////////////////////////////
  822. // IOleObjectImpl
  823. template <class T>
  824. class ATL_NO_VTABLE IOleObjectImpl
  825. {
  826. public:
  827. // IUnknown
  828. //
  829. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  830. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleObjectImpl)
  831. // IOleObject
  832. //
  833. STDMETHOD(SetClientSite)(IOleClientSite *pClientSite)
  834. {
  835. T* pT = static_cast<T*>(this);
  836. ATLTRACE(_T("IOleObjectImpl::SetClientSite\n"));
  837. return pT->IOleObject_SetClientSite(pClientSite);
  838. }
  839. STDMETHOD(GetClientSite)(IOleClientSite **ppClientSite)
  840. {
  841. T* pT = static_cast<T*>(this);
  842. ATLTRACE(_T("IOleObjectImpl::GetClientSite\n"));
  843. return pT->IOleObject_GetClientSite(ppClientSite);
  844. }
  845. STDMETHOD(SetHostNames)(LPCOLESTR /* szContainerApp */, LPCOLESTR /* szContainerObj */)
  846. {
  847. ATLTRACE(_T("IOleObjectImpl::SetHostNames\n"));
  848. return S_OK;
  849. }
  850. STDMETHOD(Close)(DWORD dwSaveOption)
  851. {
  852. T* pT = static_cast<T*>(this);
  853. ATLTRACE(_T("IOleObjectImpl::Close\n"));
  854. return pT->IOleObject_Close(dwSaveOption);
  855. }
  856. STDMETHOD(SetMoniker)(DWORD /* dwWhichMoniker */, IMoniker* /* pmk */)
  857. {
  858. ATLTRACENOTIMPL(_T("IOleObjectImpl::SetMoniker"));
  859. }
  860. STDMETHOD(GetMoniker)(DWORD /* dwAssign */, DWORD /* dwWhichMoniker */, IMoniker** /* ppmk */)
  861. {
  862. ATLTRACENOTIMPL(_T("IOleObjectImpl::GetMoniker"));
  863. }
  864. STDMETHOD(InitFromData)(IDataObject* /* pDataObject */, BOOL /* fCreation */, DWORD /* dwReserved */)
  865. {
  866. ATLTRACENOTIMPL(_T("IOleObjectImpl::InitFromData"));
  867. }
  868. STDMETHOD(GetClipboardData)(DWORD /* dwReserved */, IDataObject** /* ppDataObject */)
  869. {
  870. ATLTRACENOTIMPL(_T("IOleObjectImpl::GetClipboardData"));
  871. }
  872. // Helpers for DoVerb - Over-rideable in user class
  873. HRESULT DoVerbPrimary(LPCRECT prcPosRect, HWND hwndParent)
  874. {
  875. T* pT = static_cast<T*>(this);
  876. BOOL bDesignMode = FALSE;
  877. CComVariant var;
  878. // if container doesn't support this property
  879. // don't allow design mode
  880. HRESULT hRes = pT->GetAmbientProperty(DISPID_AMBIENT_USERMODE, var);
  881. if (SUCCEEDED(hRes) && var.vt == VT_BOOL && !var.boolVal)
  882. bDesignMode = TRUE;
  883. if (bDesignMode)
  884. return pT->DoVerbProperties(prcPosRect, hwndParent);
  885. else
  886. return pT->DoVerbInPlaceActivate(prcPosRect, hwndParent);
  887. }
  888. HRESULT DoVerbShow(LPCRECT prcPosRect, HWND /* hwndParent */)
  889. {
  890. T* pT = static_cast<T*>(this);
  891. return pT->InPlaceActivate(OLEIVERB_SHOW, prcPosRect);
  892. }
  893. HRESULT DoVerbInPlaceActivate(LPCRECT prcPosRect, HWND /* hwndParent */)
  894. {
  895. T* pT = static_cast<T*>(this);
  896. return pT->InPlaceActivate(OLEIVERB_INPLACEACTIVATE, prcPosRect);
  897. }
  898. HRESULT DoVerbUIActivate(LPCRECT prcPosRect, HWND /* hwndParent */)
  899. {
  900. T* pT = static_cast<T*>(this);
  901. return pT->InPlaceActivate(OLEIVERB_UIACTIVATE, prcPosRect);
  902. }
  903. HRESULT DoVerbHide(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  904. {
  905. T* pT = static_cast<T*>(this);
  906. pT->UIDeactivate();
  907. if (pT->m_hWnd)
  908. pT->ShowWindow(SW_HIDE);
  909. return S_OK;
  910. }
  911. HRESULT DoVerbOpen(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  912. {
  913. return S_OK;
  914. }
  915. HRESULT DoVerbDiscardUndo(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  916. {
  917. return S_OK;
  918. }
  919. STDMETHOD(DoVerb)(LONG iVerb, LPMSG /* lpmsg */, IOleClientSite* /* pActiveSite */, LONG /* lindex */,
  920. HWND hwndParent, LPCRECT lprcPosRect)
  921. {
  922. T* pT = static_cast<T*>(this);
  923. ATLTRACE(_T("IOleObjectImpl::DoVerb\n"));
  924. _ASSERTE(pT->m_spClientSite);
  925. HRESULT hr = E_NOTIMPL;
  926. switch (iVerb)
  927. {
  928. case OLEIVERB_PRIMARY:
  929. hr = pT->DoVerbPrimary(lprcPosRect, hwndParent);
  930. break;
  931. case OLEIVERB_SHOW:
  932. hr = pT->DoVerbShow(lprcPosRect, hwndParent);
  933. break;
  934. case OLEIVERB_INPLACEACTIVATE:
  935. hr = pT->DoVerbInPlaceActivate(lprcPosRect, hwndParent);
  936. break;
  937. case OLEIVERB_UIACTIVATE:
  938. hr = pT->DoVerbUIActivate(lprcPosRect, hwndParent);
  939. break;
  940. case OLEIVERB_HIDE:
  941. hr = pT->DoVerbHide(lprcPosRect, hwndParent);
  942. break;
  943. case OLEIVERB_OPEN:
  944. hr = pT->DoVerbOpen(lprcPosRect, hwndParent);
  945. break;
  946. case OLEIVERB_DISCARDUNDOSTATE:
  947. hr = pT->DoVerbDiscardUndo(lprcPosRect, hwndParent);
  948. break;
  949. case OLEIVERB_PROPERTIES:
  950. hr = pT->DoVerbProperties(lprcPosRect, hwndParent);
  951. }
  952. return hr;
  953. }
  954. STDMETHOD(EnumVerbs)(IEnumOLEVERB **ppEnumOleVerb)
  955. {
  956. ATLTRACE(_T("IOleObjectImpl::EnumVerbs\n"));
  957. _ASSERTE(ppEnumOleVerb);
  958. if (!ppEnumOleVerb)
  959. return E_POINTER;
  960. return OleRegEnumVerbs(T::GetObjectCLSID(), ppEnumOleVerb);
  961. }
  962. STDMETHOD(Update)(void)
  963. {
  964. ATLTRACE(_T("IOleObjectImpl::Update\n"));
  965. return S_OK;
  966. }
  967. STDMETHOD(IsUpToDate)(void)
  968. {
  969. ATLTRACE(_T("IOleObjectImpl::IsUpToDate\n"));
  970. return S_OK;
  971. }
  972. STDMETHOD(GetUserClassID)(CLSID *pClsid)
  973. {
  974. ATLTRACE(_T("IOleObjectImpl::GetUserClassID\n"));
  975. _ASSERTE(pClsid);
  976. if (!pClsid)
  977. return E_POINTER;
  978. *pClsid = T::GetObjectCLSID();
  979. return S_OK;
  980. }
  981. STDMETHOD(GetUserType)(DWORD dwFormOfType, LPOLESTR *pszUserType)
  982. {
  983. ATLTRACE(_T("IOleObjectImpl::GetUserType\n"));
  984. return OleRegGetUserType(T::GetObjectCLSID(), dwFormOfType, pszUserType);
  985. }
  986. STDMETHOD(SetExtent)(DWORD dwDrawAspect, SIZEL *psizel)
  987. {
  988. T* pT = static_cast<T*>(this);
  989. ATLTRACE(_T("IOleObjectImpl::SetExtent\n"));
  990. return pT->IOleObject_SetExtent(dwDrawAspect, psizel);
  991. }
  992. STDMETHOD(GetExtent)(DWORD dwDrawAspect, SIZEL *psizel)
  993. {
  994. T* pT = static_cast<T*>(this);
  995. ATLTRACE(_T("IOleObjectImpl::GetExtent\n"));
  996. if (dwDrawAspect != DVASPECT_CONTENT)
  997. return E_FAIL;
  998. if (psizel == NULL)
  999. return E_POINTER;
  1000. *psizel = pT->m_sizeExtent;
  1001. return S_OK;
  1002. }
  1003. STDMETHOD(Advise)(IAdviseSink *pAdvSink, DWORD *pdwConnection)
  1004. {
  1005. T* pT = static_cast<T*>(this);
  1006. ATLTRACE(_T("IOleObjectImpl::Advise\n"));
  1007. return pT->IOleObject_Advise(pAdvSink, pdwConnection);
  1008. }
  1009. STDMETHOD(Unadvise)(DWORD dwConnection)
  1010. {
  1011. T* pT = static_cast<T*>(this);
  1012. ATLTRACE(_T("IOleObjectImpl::Unadvise\n"));
  1013. HRESULT hRes = E_FAIL;
  1014. if (pT->m_spOleAdviseHolder != NULL)
  1015. hRes = pT->m_spOleAdviseHolder->Unadvise(dwConnection);
  1016. return hRes;
  1017. }
  1018. STDMETHOD(EnumAdvise)(IEnumSTATDATA **ppenumAdvise)
  1019. {
  1020. T* pT = static_cast<T*>(this);
  1021. ATLTRACE(_T("IOleObjectImpl::EnumAdvise\n"));
  1022. HRESULT hRes = E_FAIL;
  1023. if (pT->m_spOleAdviseHolder != NULL)
  1024. hRes = pT->m_spOleAdviseHolder->EnumAdvise(ppenumAdvise);
  1025. return hRes;
  1026. }
  1027. STDMETHOD(GetMiscStatus)(DWORD dwAspect, DWORD *pdwStatus)
  1028. {
  1029. ATLTRACE(_T("IOleObjectImpl::GetMiscStatus\n"));
  1030. return OleRegGetMiscStatus(T::GetObjectCLSID(), dwAspect, pdwStatus);
  1031. }
  1032. STDMETHOD(SetColorScheme)(LOGPALETTE* /* pLogpal */)
  1033. {
  1034. ATLTRACENOTIMPL(_T("IOleObjectImpl::SetColorScheme"));
  1035. }
  1036. };
  1037. //local struct used for implementation
  1038. #pragma pack(push, 1)
  1039. struct _ATL_DLGTEMPLATEEX
  1040. {
  1041. WORD dlgVer;
  1042. WORD signature;
  1043. DWORD helpID;
  1044. DWORD exStyle;
  1045. DWORD style;
  1046. WORD cDlgItems;
  1047. short x;
  1048. short y;
  1049. short cx;
  1050. short cy;
  1051. };
  1052. #pragma pack(pop)
  1053. //////////////////////////////////////////////////////////////////////////////
  1054. // IPropertyPageImpl
  1055. template <class T>
  1056. class ATL_NO_VTABLE IPropertyPageImpl
  1057. {
  1058. public:
  1059. // IUnknown
  1060. //
  1061. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1062. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleControlImpl)
  1063. void SetDirty(BOOL bDirty)
  1064. {
  1065. T* pT = static_cast<T*>(this);
  1066. if (!pT->m_bDirty && bDirty)
  1067. pT->m_pPageSite->OnStatusChange(PROPPAGESTATUS_DIRTY | PROPPAGESTATUS_VALIDATE);
  1068. pT->m_bDirty = bDirty;
  1069. }
  1070. IPropertyPageImpl()
  1071. {
  1072. T* pT = static_cast<T*>(this);
  1073. pT->m_pPageSite = NULL;
  1074. pT->m_size.cx = 0;
  1075. pT->m_size.cy = 0;
  1076. pT->m_dwTitleID = 0;
  1077. pT->m_dwHelpFileID = 0;
  1078. pT->m_dwDocStringID = 0;
  1079. pT->m_dwHelpContext = 0;
  1080. pT->m_ppUnk = NULL;
  1081. pT->m_nObjects = 0;
  1082. pT->m_bDirty = FALSE;
  1083. pT->m_hWnd = NULL;
  1084. }
  1085. ~IPropertyPageImpl()
  1086. {
  1087. T* pT = static_cast<T*>(this);
  1088. if (pT->m_pPageSite != NULL)
  1089. pT->m_pPageSite->Release();
  1090. for (UINT i = 0; i < m_nObjects; i++)
  1091. pT->m_ppUnk[i]->Release();
  1092. delete[] pT->m_ppUnk;
  1093. }
  1094. // IPropertyPage
  1095. //
  1096. STDMETHOD(SetPageSite)(IPropertyPageSite *pPageSite)
  1097. {
  1098. T* pT = static_cast<T*>(this);
  1099. ATLTRACE(_T("IPropertyPageImpl::SetPageSite\n"));
  1100. if (!pPageSite && pT->m_pPageSite)
  1101. {
  1102. pT->m_pPageSite->Release();
  1103. return S_OK;
  1104. }
  1105. if (!pPageSite && !pT->m_pPageSite)
  1106. return S_OK;
  1107. if (pPageSite && pT->m_pPageSite)
  1108. {
  1109. ATLTRACE(_T("Error : setting page site again with non NULL value\n"));
  1110. return E_UNEXPECTED;
  1111. }
  1112. pT->m_pPageSite = pPageSite;
  1113. pT->m_pPageSite->AddRef();
  1114. return S_OK;
  1115. }
  1116. STDMETHOD(Activate)(HWND hWndParent, LPCRECT pRect, BOOL /* bModal */)
  1117. {
  1118. T* pT = static_cast<T*>(this);
  1119. ATLTRACE(_T("IPropertyPageImpl::Activate\n"));
  1120. if (pRect == NULL)
  1121. {
  1122. ATLTRACE(_T("Error : Passed a NULL rect\n"));
  1123. return E_POINTER;
  1124. }
  1125. pT->m_hWnd = pT->Create(hWndParent);
  1126. Move(pRect);
  1127. m_size.cx = pRect->right - pRect->left;
  1128. m_size.cy = pRect->bottom - pRect->top;
  1129. return S_OK;
  1130. }
  1131. STDMETHOD(Deactivate)( void)
  1132. {
  1133. T* pT = static_cast<T*>(this);
  1134. ATLTRACE(_T("IPropertyPageImpl::Deactivate\n"));
  1135. if (pT->m_hWnd)
  1136. {
  1137. ATLTRACE(_T("Destroying Dialog\n"));
  1138. if (::IsWindow(pT->m_hWnd))
  1139. pT->DestroyWindow();
  1140. pT->m_hWnd = NULL;
  1141. }
  1142. return S_OK;
  1143. }
  1144. STDMETHOD(GetPageInfo)(PROPPAGEINFO *pPageInfo)
  1145. {
  1146. T* pT = static_cast<T*>(this);
  1147. ATLTRACE(_T("IPropertyPageImpl::GetPageInfo\n"));
  1148. if (pPageInfo == NULL)
  1149. {
  1150. ATLTRACE(_T("Error : PROPPAGEINFO passed == NULL\n"));
  1151. return E_POINTER;
  1152. }
  1153. HRSRC hRsrc = FindResource(_Module.GetResourceInstance(),
  1154. MAKEINTRESOURCE(T::IDD), RT_DIALOG);
  1155. if (hRsrc == NULL)
  1156. {
  1157. ATLTRACE(_T("Could not find resource template\n"));
  1158. return E_UNEXPECTED;
  1159. }
  1160. HGLOBAL hGlob = LoadResource(_Module.GetResourceInstance(), hRsrc);
  1161. DLGTEMPLATE* pTemp = (DLGTEMPLATE*)LockResource(hGlob);
  1162. if (pTemp == NULL)
  1163. {
  1164. ATLTRACE(_T("Could not load resource template\n"));
  1165. return E_UNEXPECTED;
  1166. }
  1167. pT->GetDialogSize(pTemp, &m_size);
  1168. pPageInfo->cb = sizeof(PROPPAGEINFO);
  1169. pPageInfo->pszTitle = LoadStringHelper(pT->m_dwTitleID);
  1170. pPageInfo->size = m_size;
  1171. pPageInfo->pszHelpFile = LoadStringHelper(pT->m_dwHelpFileID);
  1172. pPageInfo->pszDocString = LoadStringHelper(pT->m_dwDocStringID);
  1173. pPageInfo->dwHelpContext = pT->m_dwHelpContext;
  1174. return S_OK;
  1175. }
  1176. STDMETHOD(SetObjects)(ULONG nObjects, IUnknown **ppUnk)
  1177. {
  1178. T* pT = static_cast<T*>(this);
  1179. ATLTRACE(_T("IPropertyPageImpl::SetObjects\n"));
  1180. if (ppUnk == NULL)
  1181. return E_POINTER;
  1182. if (pT->m_ppUnk != NULL && pT->m_nObjects > 0)
  1183. {
  1184. for (UINT iObj = 0; iObj < pT->m_nObjects; iObj++)
  1185. pT->m_ppUnk[iObj]->Release();
  1186. delete [] pT->m_ppUnk;
  1187. }
  1188. pT->m_ppUnk = NULL;
  1189. ATLTRY(pT->m_ppUnk = new IUnknown*[nObjects]);
  1190. if (pT->m_ppUnk == NULL)
  1191. return E_OUTOFMEMORY;
  1192. for (UINT i = 0; i < nObjects; i++)
  1193. {
  1194. ppUnk[i]->AddRef();
  1195. pT->m_ppUnk[i] = ppUnk[i];
  1196. }
  1197. pT->m_nObjects = nObjects;
  1198. return S_OK;
  1199. }
  1200. STDMETHOD(Show)(UINT nCmdShow)
  1201. {
  1202. T* pT = static_cast<T*>(this);
  1203. ATLTRACE(_T("IPropertyPageImpl::Show\n"));
  1204. if (pT->m_hWnd == NULL)
  1205. return E_UNEXPECTED;
  1206. ShowWindow(pT->m_hWnd, nCmdShow);
  1207. return S_OK;
  1208. }
  1209. STDMETHOD(Move)(LPCRECT pRect)
  1210. {
  1211. T* pT = static_cast<T*>(this);
  1212. ATLTRACE(_T("IPropertyPageImpl::Move\n"));
  1213. if (pT->m_hWnd == NULL)
  1214. return E_UNEXPECTED;
  1215. if (pRect == NULL)
  1216. return E_POINTER;
  1217. MoveWindow(pT->m_hWnd, pRect->left, pRect->top, pRect->right - pRect->left,
  1218. pRect->bottom - pRect->top, TRUE);
  1219. return S_OK;
  1220. }
  1221. STDMETHOD(IsPageDirty)(void)
  1222. {
  1223. T* pT = static_cast<T*>(this);
  1224. ATLTRACE(_T("IPropertyPageImpl::IsPageDirty\n"));
  1225. return pT->m_bDirty ? S_OK : S_FALSE;
  1226. }
  1227. STDMETHOD(Apply)(void)
  1228. {
  1229. T* pT = static_cast<T*>(this);
  1230. ATLTRACE(_T("IPropertyPageImpl::Apply\n"));
  1231. return S_OK;
  1232. }
  1233. STDMETHOD(Help)(LPCOLESTR pszHelpDir)
  1234. {
  1235. T* pT = static_cast<T*>(this);
  1236. USES_CONVERSION;
  1237. ATLTRACE(_T("IPropertyPageImpl::Help\n"));
  1238. WinHelp(pT->m_hWnd, OLE2CT(pszHelpDir), HELP_CONTEXTPOPUP, NULL);
  1239. return S_OK;
  1240. }
  1241. STDMETHOD(TranslateAccelerator)(MSG *pMsg)
  1242. {
  1243. T* pT = static_cast<T*>(this);
  1244. ATLTRACE(_T("IPropertyPageImpl::TranslateAccelerator\n"));
  1245. if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) &&
  1246. (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST))
  1247. return S_FALSE;
  1248. return (IsDialogMessage(pT->m_hWnd, pMsg)) ? S_OK : S_FALSE;
  1249. }
  1250. IPropertyPageSite* m_pPageSite;
  1251. IUnknown** m_ppUnk;
  1252. ULONG m_nObjects;
  1253. SIZE m_size;
  1254. UINT m_dwTitleID;
  1255. UINT m_dwHelpFileID;
  1256. UINT m_dwDocStringID;
  1257. DWORD m_dwHelpContext;
  1258. BOOL m_bDirty;
  1259. //methods
  1260. public:
  1261. BEGIN_MSG_MAP(IPropertyPageImpl<T>)
  1262. MESSAGE_HANDLER(WM_STYLECHANGING, OnStyleChange)
  1263. END_MSG_MAP()
  1264. LRESULT OnStyleChange(UINT, WPARAM wParam, LPARAM lParam, BOOL&)
  1265. {
  1266. if (wParam == GWL_EXSTYLE)
  1267. {
  1268. LPSTYLESTRUCT lpss = (LPSTYLESTRUCT) lParam;
  1269. lpss->styleNew |= WS_EX_CONTROLPARENT;
  1270. return 0;
  1271. }
  1272. return 1;
  1273. }
  1274. LPOLESTR LoadStringHelper(UINT idRes)
  1275. {
  1276. USES_CONVERSION;
  1277. TCHAR szTemp[_MAX_PATH];
  1278. LPOLESTR sz = (LPOLESTR)CoTaskMemAlloc(_MAX_PATH*sizeof(OLECHAR));
  1279. if (sz == NULL)
  1280. return NULL;
  1281. sz[0] = NULL;
  1282. if (LoadString(_Module.GetResourceInstance(), idRes, szTemp, _MAX_PATH))
  1283. ocscpy(sz, T2OLE(szTemp));
  1284. else
  1285. {
  1286. ATLTRACE(_T("Error : Failed to load string from res\n"));
  1287. }
  1288. return sz;
  1289. }
  1290. void GetDialogSize(const DLGTEMPLATE* pTemplate, SIZE* pSize)
  1291. {
  1292. // If the dialog has a font we use it otherwise we default
  1293. // to the system font.
  1294. if (HasFont(pTemplate))
  1295. {
  1296. TCHAR szFace[LF_FACESIZE];
  1297. WORD wFontSize = 0;
  1298. GetFont(pTemplate, szFace, &wFontSize);
  1299. GetSizeInDialogUnits(pTemplate, pSize);
  1300. ConvertDialogUnitsToPixels(szFace, wFontSize, pSize);
  1301. }
  1302. else
  1303. {
  1304. GetSizeInDialogUnits(pTemplate, pSize);
  1305. LONG nDlgBaseUnits = GetDialogBaseUnits();
  1306. pSize->cx = MulDiv(pSize->cx, LOWORD(nDlgBaseUnits), 4);
  1307. pSize->cy = MulDiv(pSize->cy, HIWORD(nDlgBaseUnits), 8);
  1308. }
  1309. }
  1310. static void ConvertDialogUnitsToPixels(LPCTSTR pszFontFace, WORD wFontSize, SIZE* pSizePixel)
  1311. {
  1312. // Attempt to create the font to be used in the dialog box
  1313. UINT cxSysChar, cySysChar;
  1314. LOGFONT lf;
  1315. HDC hDC = ::GetDC(NULL);
  1316. int cxDlg = pSizePixel->cx;
  1317. int cyDlg = pSizePixel->cy;
  1318. ZeroMemory(&lf, sizeof(LOGFONT));
  1319. lf.lfHeight = -MulDiv(wFontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
  1320. lf.lfWeight = FW_NORMAL;
  1321. lf.lfCharSet = DEFAULT_CHARSET;
  1322. lstrcpy(lf.lfFaceName, pszFontFace);
  1323. HFONT hNewFont = CreateFontIndirect(&lf);
  1324. if (hNewFont != NULL)
  1325. {
  1326. TEXTMETRIC tm;
  1327. SIZE size;
  1328. HFONT hFontOld = (HFONT)SelectObject(hDC, hNewFont);
  1329. GetTextMetrics(hDC, &tm);
  1330. cySysChar = tm.tmHeight + tm.tmExternalLeading;
  1331. ::GetTextExtentPoint(hDC,
  1332. _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52,
  1333. &size);
  1334. cxSysChar = (size.cx + 26) / 52;
  1335. SelectObject(hDC, hFontOld);
  1336. DeleteObject(hNewFont);
  1337. }
  1338. else
  1339. {
  1340. // Could not create the font so just use the system's values
  1341. cxSysChar = LOWORD(GetDialogBaseUnits());
  1342. cySysChar = HIWORD(GetDialogBaseUnits());
  1343. }
  1344. ::ReleaseDC(NULL, hDC);
  1345. // Translate dialog units to pixels
  1346. pSizePixel->cx = MulDiv(cxDlg, cxSysChar, 4);
  1347. pSizePixel->cy = MulDiv(cyDlg, cySysChar, 8);
  1348. }
  1349. static BOOL IsDialogEx(const DLGTEMPLATE* pTemplate)
  1350. {
  1351. return ((_ATL_DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF;
  1352. }
  1353. static BOOL HasFont(const DLGTEMPLATE* pTemplate)
  1354. {
  1355. return (DS_SETFONT &
  1356. (IsDialogEx(pTemplate) ?
  1357. ((_ATL_DLGTEMPLATEEX*)pTemplate)->style : pTemplate->style));
  1358. }
  1359. static BYTE* GetFontSizeField(const DLGTEMPLATE* pTemplate)
  1360. {
  1361. BOOL bDialogEx = IsDialogEx(pTemplate);
  1362. WORD* pw;
  1363. if (bDialogEx)
  1364. pw = (WORD*)((_ATL_DLGTEMPLATEEX*)pTemplate + 1);
  1365. else
  1366. pw = (WORD*)(pTemplate + 1);
  1367. if (*pw == (WORD)-1) // Skip menu name string or ordinal
  1368. pw += 2; // WORDs
  1369. else
  1370. while(*pw++);
  1371. if (*pw == (WORD)-1) // Skip class name string or ordinal
  1372. pw += 2; // WORDs
  1373. else
  1374. while(*pw++);
  1375. while (*pw++); // Skip caption string
  1376. return (BYTE*)pw;
  1377. }
  1378. static BOOL GetFont(const DLGTEMPLATE* pTemplate, TCHAR* pszFace, WORD* pFontSize)
  1379. {
  1380. USES_CONVERSION;
  1381. if (!HasFont(pTemplate))
  1382. return FALSE;
  1383. BYTE* pb = GetFontSizeField(pTemplate);
  1384. *pFontSize = *(WORD*)pb;
  1385. // Skip over font attributes to get to the font name
  1386. pb += sizeof(WORD) * (IsDialogEx(pTemplate) ? 3 : 1);
  1387. _tcscpy(pszFace, W2T((WCHAR*)pb));
  1388. return TRUE;
  1389. }
  1390. static void GetSizeInDialogUnits(const DLGTEMPLATE* pTemplate, SIZE* pSize)
  1391. {
  1392. if (IsDialogEx(pTemplate))
  1393. {
  1394. pSize->cx = ((_ATL_DLGTEMPLATEEX*)pTemplate)->cx;
  1395. pSize->cy = ((_ATL_DLGTEMPLATEEX*)pTemplate)->cy;
  1396. }
  1397. else
  1398. {
  1399. pSize->cx = pTemplate->cx;
  1400. pSize->cy = pTemplate->cy;
  1401. }
  1402. }
  1403. };
  1404. //////////////////////////////////////////////////////////////////////////////
  1405. // IPropertyPage2Impl
  1406. template <class T>
  1407. class ATL_NO_VTABLE IPropertyPage2Impl : public IPropertyPageImpl<T>
  1408. {
  1409. public:
  1410. STDMETHOD(EditProperty)(DISPID dispID)
  1411. {
  1412. ATLTRACENOTIMPL(_T("IPropertyPage2Impl::EditProperty\n"));
  1413. }
  1414. };
  1415. //////////////////////////////////////////////////////////////////////////////
  1416. // IPerPropertyBrowsingImpl
  1417. template <class T>
  1418. class ATL_NO_VTABLE IPerPropertyBrowsingImpl
  1419. {
  1420. public:
  1421. // IUnknown
  1422. //
  1423. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1424. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPerPropertyBrowsingImpl)
  1425. STDMETHOD(GetDisplayString)(DISPID dispID,BSTR *pBstr)
  1426. {
  1427. ATLTRACE(_T("IPerPropertyBrowsingImpl::GetDisplayString\n"));
  1428. T* pT = static_cast<T*>(this);
  1429. CComVariant var;
  1430. if (FAILED(CComDispatchDriver::GetProperty(pT, dispID, &var)))
  1431. {
  1432. *pBstr = NULL;
  1433. return S_FALSE;
  1434. }
  1435. BSTR bstrTemp = var.bstrVal;
  1436. if (var.vt != VT_BSTR)
  1437. {
  1438. CComVariant varDest;
  1439. if (FAILED(::VariantChangeType(&varDest, &var, VARIANT_NOVALUEPROP, VT_BSTR)))
  1440. {
  1441. *pBstr = NULL;
  1442. return S_FALSE;
  1443. }
  1444. bstrTemp = varDest.bstrVal;
  1445. }
  1446. *pBstr = SysAllocString(bstrTemp);
  1447. return S_OK;
  1448. }
  1449. STDMETHOD(MapPropertyToPage)(DISPID dispID, CLSID *pClsid)
  1450. {
  1451. ATLTRACE(_T("IPerPropertyBrowsingImpl::MapPropertyToPage\n"));
  1452. T* pT = static_cast<T*>(this);
  1453. ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
  1454. _ASSERTE(pMap != NULL);
  1455. for(int i = 0; pMap[i].pclsidPropPage != NULL; i++)
  1456. {
  1457. if (pMap[i].szDesc == NULL)
  1458. continue;
  1459. if (pMap[i].dispid == dispID)
  1460. {
  1461. _ASSERTE(pMap[i].pclsidPropPage != NULL);
  1462. *pClsid = *(pMap[i].pclsidPropPage);
  1463. return S_OK;
  1464. }
  1465. }
  1466. *pClsid = CLSID_NULL;
  1467. return E_INVALIDARG;
  1468. }
  1469. STDMETHOD(GetPredefinedStrings)(DISPID dispID, CALPOLESTR *pCaStringsOut,CADWORD *pCaCookiesOut)
  1470. {
  1471. dispID;
  1472. ATLTRACE(_T("IPerPropertyBrowsingImpl::GetPredefinedStrings\n"));
  1473. if (pCaStringsOut == NULL || pCaCookiesOut == NULL)
  1474. return E_POINTER;
  1475. pCaStringsOut->cElems = 0;
  1476. pCaStringsOut->pElems = NULL;
  1477. pCaCookiesOut->cElems = 0;
  1478. pCaCookiesOut->pElems = NULL;
  1479. return S_OK;
  1480. }
  1481. STDMETHOD(GetPredefinedValue)(DISPID /*dispID*/, DWORD /*dwCookie*/, VARIANT* /*pVarOut*/)
  1482. {
  1483. ATLTRACENOTIMPL(_T("IPerPropertyBrowsingImpl::GetPredefinedValue"));
  1484. }
  1485. };
  1486. //////////////////////////////////////////////////////////////////////////////
  1487. // IViewObjectExImpl
  1488. template <class T>
  1489. class ATL_NO_VTABLE IViewObjectExImpl
  1490. {
  1491. public:
  1492. // IUnknown
  1493. //
  1494. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1495. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IViewObjectExImpl)
  1496. // IViewObject
  1497. //
  1498. STDMETHOD(Draw)(DWORD dwDrawAspect, LONG lindex, void *pvAspect,
  1499. DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw,
  1500. LPCRECTL prcBounds, LPCRECTL prcWBounds,
  1501. BOOL (__stdcall * /*pfnContinue*/)(DWORD_PTR dwContinue),
  1502. DWORD_PTR /*dwContinue*/)
  1503. {
  1504. T* pT = static_cast<T*>(this);
  1505. ATLTRACE(_T("IViewObjectExImpl::Draw\n"));
  1506. return pT->IViewObject_Draw(dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, hdcDraw,
  1507. prcBounds, prcWBounds);
  1508. }
  1509. STDMETHOD(GetColorSet)(DWORD /* dwDrawAspect */,LONG /* lindex */, void* /* pvAspect */, DVTARGETDEVICE* /* ptd */, HDC /* hicTargetDev */, LOGPALETTE** /* ppColorSet */)
  1510. {
  1511. ATLTRACENOTIMPL(_T("IViewObjectExImpl::GetColorSet"));
  1512. }
  1513. STDMETHOD(Freeze)(DWORD /* dwDrawAspect */, LONG /* lindex */, void* /* pvAspect */,DWORD* /* pdwFreeze */)
  1514. {
  1515. ATLTRACENOTIMPL(_T("IViewObjectExImpl::Freeze"));
  1516. }
  1517. STDMETHOD(Unfreeze)(DWORD /* dwFreeze */)
  1518. {
  1519. ATLTRACENOTIMPL(_T("IViewObjectExImpl::Unfreeze"));
  1520. }
  1521. STDMETHOD(SetAdvise)(DWORD /* aspects */, DWORD /* advf */, IAdviseSink* pAdvSink)
  1522. {
  1523. T* pT = static_cast<T*>(this);
  1524. ATLTRACE(_T("IViewObjectExImpl::SetAdvise\n"));
  1525. pT->m_spAdviseSink = pAdvSink;
  1526. return S_OK;
  1527. }
  1528. STDMETHOD(GetAdvise)(DWORD* /* pAspects */, DWORD* /* pAdvf */, IAdviseSink** ppAdvSink)
  1529. {
  1530. T* pT = static_cast<T*>(this);
  1531. ATLTRACE(_T("IViewObjectExImpl::GetAdvise\n"));
  1532. if (ppAdvSink != NULL)
  1533. {
  1534. *ppAdvSink = pT->m_spAdviseSink;
  1535. if (pT->m_spAdviseSink)
  1536. pT->m_spAdviseSink.p->AddRef();
  1537. }
  1538. return S_OK;
  1539. }
  1540. // IViewObject2
  1541. //
  1542. STDMETHOD(GetExtent)(DWORD /* dwDrawAspect */, LONG /* lindex */, DVTARGETDEVICE* /* ptd */, LPSIZEL lpsizel)
  1543. {
  1544. T* pT = static_cast<T*>(this);
  1545. ATLTRACE(_T("IViewObjectExImpl::GetExtent\n"));
  1546. *lpsizel = pT->m_sizeExtent;
  1547. return S_OK;
  1548. }
  1549. // IViewObjectEx
  1550. //
  1551. STDMETHOD(GetRect)(DWORD /* dwAspect */, LPRECTL /* pRect */)
  1552. {
  1553. ATLTRACENOTIMPL(_T("IViewObjectExImpl::GetRect"));
  1554. }
  1555. STDMETHOD(GetViewStatus)(DWORD* pdwStatus)
  1556. {
  1557. ATLTRACE(_T("IViewObjectExImpl::GetViewStatus\n"));
  1558. *pdwStatus =
  1559. // VIEWSTATUS_DVASPECTOPAQUE | VIEWSTATUS_DVASPECTTRANSPARENT |
  1560. // VIEWSTATUS_SOLIDBKGND |
  1561. VIEWSTATUS_OPAQUE;
  1562. return S_OK;
  1563. }
  1564. STDMETHOD(QueryHitPoint)(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG /* lCloseHint */, DWORD *pHitResult)
  1565. {
  1566. ATLTRACE(_T("IViewObjectExImpl::QueryHitPoint\n"));
  1567. if (dwAspect == DVASPECT_CONTENT)
  1568. {
  1569. *pHitResult = PtInRect(pRectBounds, ptlLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  1570. return S_OK;
  1571. }
  1572. ATLTRACE(_T("Wrong DVASPECT\n"));
  1573. return E_FAIL;
  1574. }
  1575. STDMETHOD(QueryHitRect)(DWORD dwAspect, LPCRECT pRectBounds, LPCRECT prcLoc, LONG /* lCloseHint */, DWORD* pHitResult)
  1576. {
  1577. ATLTRACE(_T("IViewObjectExImpl::QueryHitRect\n"));
  1578. if (dwAspect == DVASPECT_CONTENT)
  1579. {
  1580. RECT rc;
  1581. *pHitResult = UnionRect(&rc, pRectBounds, prcLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  1582. return S_OK;
  1583. }
  1584. ATLTRACE(_T("Wrong DVASPECT\n"));
  1585. return E_FAIL;
  1586. }
  1587. STDMETHOD(GetNaturalExtent)(DWORD dwAspect, LONG /* lindex */, DVTARGETDEVICE* /* ptd */, HDC /* hicTargetDev */, DVEXTENTINFO* pExtentInfo , LPSIZEL psizel)
  1588. {
  1589. T* pT = static_cast<T*>(this);
  1590. ATLTRACE(_T("IViewObjectExImpl::GetNaturalExtent\n"));
  1591. HRESULT hRes = E_FAIL;
  1592. if (dwAspect == DVASPECT_CONTENT)
  1593. {
  1594. if (pExtentInfo->dwExtentMode == DVEXTENT_CONTENT)
  1595. {
  1596. *psizel = pT->m_sizeNatural;
  1597. hRes = S_OK;
  1598. }
  1599. }
  1600. return hRes;
  1601. }
  1602. public:
  1603. };
  1604. //////////////////////////////////////////////////////////////////////////////
  1605. // IOleInPlaceObjectWindowlessImpl
  1606. //
  1607. template <class T>
  1608. class ATL_NO_VTABLE IOleInPlaceObjectWindowlessImpl
  1609. {
  1610. public:
  1611. // IUnknown
  1612. //
  1613. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1614. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleInPlaceObjectWindowlessImpl)
  1615. // IOleWindow
  1616. //
  1617. // Change IOleInPlaceActiveObject::GetWindow as well
  1618. STDMETHOD(GetWindow)(HWND* phwnd)
  1619. {
  1620. ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::GetWindow\n"));
  1621. T* pT = static_cast<T*>(this);
  1622. HRESULT hRes = E_POINTER;
  1623. if (pT->m_bWasOnceWindowless)
  1624. return E_FAIL;
  1625. if (phwnd != NULL)
  1626. {
  1627. *phwnd = pT->m_hWnd;
  1628. hRes = (*phwnd == NULL) ? E_UNEXPECTED : S_OK;
  1629. }
  1630. return hRes;
  1631. }
  1632. STDMETHOD(ContextSensitiveHelp)(BOOL /* fEnterMode */)
  1633. {
  1634. ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::ContextSensitiveHelp"));
  1635. }
  1636. // IOleInPlaceObject
  1637. //
  1638. STDMETHOD(InPlaceDeactivate)(void)
  1639. {
  1640. T* pT = static_cast<T*>(this);
  1641. ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::InPlaceDeactivate\n"));
  1642. return pT->IOleInPlaceObject_InPlaceDeactivate();
  1643. }
  1644. STDMETHOD(UIDeactivate)(void)
  1645. {
  1646. T* pT = static_cast<T*>(this);
  1647. ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::UIDeactivate\n"));
  1648. return pT->IOleInPlaceObject_UIDeactivate();
  1649. }
  1650. STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip)
  1651. {
  1652. T* pT = static_cast<T*>(this);
  1653. ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::SetObjectRects\n"));
  1654. return pT->IOleInPlaceObject_SetObjectRects(prcPos, prcClip);
  1655. }
  1656. STDMETHOD(ReactivateAndUndo)(void)
  1657. {
  1658. ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::ReactivateAndUndo"));
  1659. }
  1660. // IOleInPlaceObjectWindowless
  1661. //
  1662. STDMETHOD(OnWindowMessage)(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
  1663. {
  1664. ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::OnWindowMessage\n"));
  1665. T* pT = static_cast<T*>(this);
  1666. return (pT->ProcessWindowMessage(pT->m_hWnd, msg, wParam, lParam, *plResult)) ? S_OK : S_FALSE;
  1667. }
  1668. STDMETHOD(GetDropTarget)(IDropTarget** /* ppDropTarget */)
  1669. {
  1670. ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::GetDropTarget"));
  1671. }
  1672. };
  1673. //////////////////////////////////////////////////////////////////////////////
  1674. // IOleInPlaceActiveObjectImpl
  1675. //
  1676. template <class T>
  1677. class ATL_NO_VTABLE IOleInPlaceActiveObjectImpl
  1678. {
  1679. public:
  1680. // IUnknown
  1681. //
  1682. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1683. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleInPlaceActiveObjectImpl)
  1684. // IOleWindow
  1685. //
  1686. // Change IOleInPlaceObjectWindowless::GetWindow as well
  1687. STDMETHOD(GetWindow)(HWND *phwnd)
  1688. {
  1689. ATLTRACE(_T("IOleInPlaceActiveObjectImpl::GetWindow\n"));
  1690. T* pT = static_cast<T*>(this);
  1691. HRESULT hRes = E_POINTER;
  1692. if (pT->m_bWasOnceWindowless)
  1693. return E_FAIL;
  1694. if (phwnd != NULL)
  1695. {
  1696. *phwnd = pT->m_hWnd;
  1697. hRes = (*phwnd == NULL) ? E_UNEXPECTED : S_OK;
  1698. }
  1699. return hRes;
  1700. }
  1701. STDMETHOD(ContextSensitiveHelp)(BOOL /* fEnterMode */)
  1702. {
  1703. ATLTRACENOTIMPL(_T("IOleInPlaceActiveObjectImpl::ContextSensitiveHelp"));
  1704. }
  1705. // IOleInPlaceActiveObject
  1706. //
  1707. STDMETHOD(TranslateAccelerator)(LPMSG /* lpmsg */)
  1708. {
  1709. ATLTRACE(_T("IOleInPlaceActiveObjectImpl::TranslateAccelerator\n"));
  1710. return E_NOTIMPL;
  1711. }
  1712. STDMETHOD(OnFrameWindowActivate)(BOOL /* fActivate */)
  1713. {
  1714. ATLTRACE(_T("IOleInPlaceActiveObjectImpl::OnFrameWindowActivate\n"));
  1715. return S_OK;
  1716. }
  1717. STDMETHOD(OnDocWindowActivate)(BOOL /* fActivate */)
  1718. {
  1719. ATLTRACE(_T("IOleInPlaceActiveObjectImpl::OnDocWindowActivate\n"));
  1720. return S_OK;
  1721. }
  1722. STDMETHOD(ResizeBorder)(LPCRECT /* prcBorder */, IOleInPlaceUIWindow* /* pUIWindow */, BOOL /* fFrameWindow */)
  1723. {
  1724. ATLTRACE(_T("IOleInPlaceActiveObjectImpl::ResizeBorder\n"));
  1725. return S_OK;
  1726. }
  1727. STDMETHOD(EnableModeless)(BOOL /* fEnable */)
  1728. {
  1729. ATLTRACE(_T("IOleInPlaceActiveObjectImpl::EnableModeless\n"));
  1730. return S_OK;
  1731. }
  1732. };
  1733. //////////////////////////////////////////////////////////////////////////////
  1734. // ISpecifyPropertyPagesImpl
  1735. template <class T>
  1736. class ATL_NO_VTABLE ISpecifyPropertyPagesImpl
  1737. {
  1738. public:
  1739. // IUnknown
  1740. //
  1741. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1742. _ATL_DEBUG_ADDREF_RELEASE_IMPL(ISpecifyPropertyPagesImpl)
  1743. // ISpecifyPropertyPages
  1744. //
  1745. STDMETHOD(GetPages)(CAUUID* pPages)
  1746. {
  1747. ATLTRACE(_T("ISpecifyPropertyPagesImpl::GetPages\n"));
  1748. T* pT = static_cast<T*>(this);
  1749. ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
  1750. return pT->ISpecifyPropertyPages_GetPages(pPages, pMap);
  1751. }
  1752. };
  1753. //////////////////////////////////////////////////////////////////////////////
  1754. // IPointerInactiveImpl
  1755. template <class T>
  1756. class ATL_NO_VTABLE IPointerInactiveImpl
  1757. {
  1758. public:
  1759. // IUnknown
  1760. //
  1761. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1762. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPointerInactiveImpl)
  1763. // IPointerInactive
  1764. //
  1765. STDMETHOD(GetActivationPolicy)(DWORD *pdwPolicy)
  1766. {
  1767. ATLTRACENOTIMPL(_T("IPointerInactiveImpl::GetActivationPolicy"));
  1768. }
  1769. STDMETHOD(OnInactiveMouseMove)(LPCRECT pRectBounds, long x, long y, DWORD dwMouseMsg)
  1770. {
  1771. ATLTRACENOTIMPL(_T("IPointerInactiveImpl::OnInactiveMouseMove"));
  1772. }
  1773. STDMETHOD(OnInactiveSetCursor)(LPCRECT pRectBounds, long x, long y, DWORD dwMouseMsg, BOOL fSetAlways)
  1774. {
  1775. ATLTRACENOTIMPL(_T("IPointerInactiveImpl::OnInactiveSetCursor"));
  1776. }
  1777. };
  1778. //////////////////////////////////////////////////////////////////////////////
  1779. // IRunnableObjectImpl
  1780. template <class T>
  1781. class ATL_NO_VTABLE IRunnableObjectImpl
  1782. {
  1783. public:
  1784. // IUnknown
  1785. //
  1786. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1787. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IRunnableObjectImpl)
  1788. // IRunnableObject
  1789. //
  1790. STDMETHOD(GetRunningClass)(LPCLSID lpClsid)
  1791. {
  1792. ATLTRACE(_T("IRunnableObjectImpl::GetRunningClass\n"));
  1793. T* pT = static_cast<T*>(this);
  1794. *lpClsid = GUID_NULL;
  1795. return E_UNEXPECTED;
  1796. }
  1797. STDMETHOD(Run)(LPBINDCTX)
  1798. {
  1799. ATLTRACE(_T("IRunnableObjectImpl::Run\n"));
  1800. return S_OK;
  1801. }
  1802. virtual BOOL STDMETHODCALLTYPE IsRunning()
  1803. {
  1804. ATLTRACE(_T("IRunnableObjectImpl::IsRunning\n"));
  1805. return TRUE;
  1806. }
  1807. STDMETHOD(LockRunning)(BOOL /*fLock*/, BOOL /*fLastUnlockCloses*/)
  1808. {
  1809. ATLTRACE(_T("IRunnableObjectImpl::LockRunning\n"));
  1810. return S_OK;
  1811. }
  1812. STDMETHOD(SetContainedObject)(BOOL /*fContained*/)
  1813. {
  1814. ATLTRACE(_T("IRunnableObjectImpl::SetContainedObject\n"));
  1815. return S_OK;
  1816. }
  1817. };
  1818. //////////////////////////////////////////////////////////////////////////////
  1819. // IDataObjectImpl
  1820. template <class T>
  1821. class ATL_NO_VTABLE IDataObjectImpl
  1822. {
  1823. public:
  1824. // IUnknown
  1825. //
  1826. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1827. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IDataObjectImpl)
  1828. // IDataObject
  1829. //
  1830. STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
  1831. {
  1832. ATLTRACE(_T("IDataObjectImpl::GetData\n"));
  1833. T* pT = (T*) this;
  1834. return pT->IDataObject_GetData(pformatetcIn, pmedium);
  1835. }
  1836. STDMETHOD(GetDataHere)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */)
  1837. {
  1838. ATLTRACENOTIMPL(_T("IDataObjectImpl::GetDataHere"));
  1839. }
  1840. STDMETHOD(QueryGetData)(FORMATETC* /* pformatetc */)
  1841. {
  1842. ATLTRACENOTIMPL(_T("IDataObjectImpl::QueryGetData"));
  1843. }
  1844. STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */)
  1845. {
  1846. ATLTRACENOTIMPL(_T("IDataObjectImpl::GetCanonicalFormatEtc"));
  1847. }
  1848. STDMETHOD(SetData)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */)
  1849. {
  1850. ATLTRACENOTIMPL(_T("IDataObjectImpl::SetData"));
  1851. }
  1852. STDMETHOD(EnumFormatEtc)(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */)
  1853. {
  1854. ATLTRACENOTIMPL(_T("IDataObjectImpl::EnumFormatEtc"));
  1855. }
  1856. STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink,
  1857. DWORD *pdwConnection)
  1858. {
  1859. ATLTRACE(_T("IDataObjectImpl::DAdvise\n"));
  1860. T* pT = static_cast<T*>(this);
  1861. HRESULT hr = S_OK;
  1862. if (pT->m_spDataAdviseHolder == NULL)
  1863. hr = CreateDataAdviseHolder(&pT->m_spDataAdviseHolder);
  1864. if (hr == S_OK)
  1865. hr = pT->m_spDataAdviseHolder->Advise((IDataObject*)this, pformatetc, advf, pAdvSink, pdwConnection);
  1866. return hr;
  1867. }
  1868. STDMETHOD(DUnadvise)(DWORD dwConnection)
  1869. {
  1870. ATLTRACE(_T("IDataObjectImpl::DUnadvise\n"));
  1871. T* pT = static_cast<T*>(this);
  1872. HRESULT hr = S_OK;
  1873. if (pT->m_spDataAdviseHolder == NULL)
  1874. hr = OLE_E_NOCONNECTION;
  1875. else
  1876. hr = pT->m_spDataAdviseHolder->Unadvise(dwConnection);
  1877. return hr;
  1878. }
  1879. STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise)
  1880. {
  1881. ATLTRACE(_T("IDataObjectImpl::EnumDAdvise\n"));
  1882. T* pT = static_cast<T*>(this);
  1883. HRESULT hr = E_FAIL;
  1884. if (pT->m_spDataAdviseHolder != NULL)
  1885. hr = pT->m_spDataAdviseHolder->EnumAdvise(ppenumAdvise);
  1886. return hr;
  1887. }
  1888. };
  1889. //////////////////////////////////////////////////////////////////////////////
  1890. // IPropertyNotifySinkCP
  1891. template <class T, class CDV = CComDynamicUnkArray >
  1892. class ATL_NO_VTABLE IPropertyNotifySinkCP :
  1893. public IConnectionPointImpl<T, &IID_IPropertyNotifySink, CDV>
  1894. {
  1895. public:
  1896. typedef CFirePropNotifyEvent _ATL_PROP_NOTIFY_EVENT_CLASS;
  1897. };
  1898. //////////////////////////////////////////////////////////////////////////////
  1899. // IObjectSafety
  1900. //
  1901. template <class T>
  1902. class ATL_NO_VTABLE IObjectSafetyImpl
  1903. {
  1904. public:
  1905. IObjectSafetyImpl()
  1906. {
  1907. m_dwSafety = 0;
  1908. }
  1909. // IUnknown
  1910. //
  1911. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1912. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IObjectSafetyImpl)
  1913. // IObjectSafety
  1914. //
  1915. STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
  1916. {
  1917. ATLTRACE(_T("IObjectSafetyImpl::GetInterfaceSafetyOptions\n"));
  1918. if (pdwSupportedOptions == NULL || pdwEnabledOptions == NULL)
  1919. return E_POINTER;
  1920. HRESULT hr = S_OK;
  1921. if (riid == IID_IDispatch)
  1922. {
  1923. *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
  1924. *pdwEnabledOptions = m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER;
  1925. }
  1926. else
  1927. {
  1928. *pdwSupportedOptions = 0;
  1929. *pdwEnabledOptions = 0;
  1930. hr = E_NOINTERFACE;
  1931. }
  1932. return hr;
  1933. }
  1934. STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
  1935. {
  1936. ATLTRACE(_T("IObjectSafetyImpl::SetInterfaceSafetyOptions\n"));
  1937. // If we're being asked to set our safe for scripting option then oblige
  1938. if (riid == IID_IDispatch)
  1939. {
  1940. // Store our current safety level to return in GetInterfaceSafetyOptions
  1941. m_dwSafety = dwEnabledOptions & dwOptionSetMask;
  1942. return S_OK;
  1943. }
  1944. return E_NOINTERFACE;
  1945. }
  1946. DWORD m_dwSafety;
  1947. };
  1948. template <class T>
  1949. class ATL_NO_VTABLE IOleLinkImpl
  1950. {
  1951. // IUnknown
  1952. //
  1953. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1954. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleLinkImpl)
  1955. STDMETHOD(SetUpdateOptions)(DWORD /* dwUpdateOpt */)
  1956. {
  1957. ATLTRACENOTIMPL(_T("IOleLinkImpl::SetUpdateOptions"));
  1958. }
  1959. STDMETHOD(GetUpdateOptions)(DWORD* /* pdwUpdateOpt */)
  1960. {
  1961. ATLTRACENOTIMPL(_T("IOleLinkImpl::GetUpdateOptions"));
  1962. }
  1963. STDMETHOD(SetSourceMoniker)(IMoniker* /* pmk */, REFCLSID /* rclsid */)
  1964. {
  1965. ATLTRACENOTIMPL(_T("IOleLinkImpl::SetSourceMoniker"));
  1966. }
  1967. STDMETHOD(GetSourceMoniker)(IMoniker** /* ppmk */)
  1968. {
  1969. ATLTRACENOTIMPL(_T("IOleLinkImpl::GetSourceMoniker"));
  1970. };
  1971. STDMETHOD(SetSourceDisplayName)(LPCOLESTR /* pszStatusText */)
  1972. {
  1973. ATLTRACENOTIMPL(_T("IOleLinkImpl::SetSourceDisplayName"));
  1974. }
  1975. STDMETHOD(GetSourceDisplayName)(LPOLESTR *ppszDisplayName)
  1976. {
  1977. ATLTRACE(_T("IOleLink::GetSourceDisplayName\n"));
  1978. *ppszDisplayName = NULL;
  1979. return E_FAIL;
  1980. }
  1981. STDMETHOD(BindToSource)(DWORD /* bindflags */, IBindCtx* /* pbc */)
  1982. {
  1983. ATLTRACENOTIMPL(_T("IOleLinkImpl::BindToSource\n"));
  1984. };
  1985. STDMETHOD(BindIfRunning)()
  1986. {
  1987. ATLTRACE(_T("IOleLinkImpl::BindIfRunning\n"));
  1988. return S_OK;
  1989. };
  1990. STDMETHOD(GetBoundSource)(IUnknown** /* ppunk */)
  1991. {
  1992. ATLTRACENOTIMPL(_T("IOleLinkImpl::GetBoundSource"));
  1993. };
  1994. STDMETHOD(UnbindSource)()
  1995. {
  1996. ATLTRACENOTIMPL(_T("IOleLinkImpl::UnbindSource"));
  1997. };
  1998. STDMETHOD(Update)(IBindCtx* /* pbc */)
  1999. {
  2000. ATLTRACENOTIMPL(_T("IOleLinkImpl::Update"));
  2001. };
  2002. };
  2003. template <class T>
  2004. class ATL_NO_VTABLE IBindStatusCallbackImpl
  2005. {
  2006. public:
  2007. // IUnknown
  2008. //
  2009. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  2010. _ATL_DEBUG_ADDREF_RELEASE_IMPL(IBindStatusCallbackImpl)
  2011. // IBindStatusCallback
  2012. //
  2013. STDMETHOD(OnStartBinding)(DWORD /* dwReserved */, IBinding *pBinding)
  2014. {
  2015. ATLTRACE(_T("IBindStatusCallbackImpl::OnStartBinding\n"));
  2016. return S_OK;
  2017. }
  2018. STDMETHOD(GetPriority)(LONG* /* pnPriority */)
  2019. {
  2020. ATLTRACENOTIMPL(_T("IBindStatusCallbackImpl::GetPriority"));
  2021. }
  2022. STDMETHOD(OnLowResource)(DWORD /* reserved */)
  2023. {
  2024. ATLTRACE(_T("IBindStatusCallbackImpl::OnLowResource\n"));
  2025. return S_OK;
  2026. }
  2027. STDMETHOD(OnProgress)(ULONG /* ulProgress */, ULONG /* ulProgressMax */, ULONG /* ulStatusCode */, LPCWSTR /* szStatusText */)
  2028. {
  2029. ATLTRACE(_T("IBindStatusCallbackImpl::OnProgress\n"));
  2030. return S_OK;
  2031. }
  2032. STDMETHOD(OnStopBinding)(HRESULT /* hresult */, LPCWSTR /* szError */)
  2033. {
  2034. ATLTRACE(_T("IBindStatusCallbackImpl::OnStopBinding\n"));
  2035. return S_OK;
  2036. }
  2037. STDMETHOD(GetBindInfo)(DWORD* /* pgrfBINDF */, BINDINFO* /* pBindInfo */)
  2038. {
  2039. ATLTRACE(_T("IBindStatusCallbackImpl::GetBindInfo\n"));
  2040. return S_OK;
  2041. }
  2042. STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
  2043. {
  2044. ATLTRACE(_T("IBindStatusCallbackImpl::OnDataAvailable\n"));
  2045. return S_OK;
  2046. }
  2047. STDMETHOD(OnObjectAvailable)(REFIID /* riid */, IUnknown* /* punk */)
  2048. {
  2049. ATLTRACE(_T("IBindStatusCallbackImpl::OnObjectAvailable\n"));
  2050. return S_OK;
  2051. }
  2052. };
  2053. template <class T>
  2054. class ATL_NO_VTABLE CBindStatusCallback :
  2055. public CComObjectRootEx<typename T::_ThreadModel::ThreadModelNoCS>,
  2056. public IBindStatusCallbackImpl<T>
  2057. {
  2058. typedef void (T::*ATL_PDATAAVAILABLE)(CBindStatusCallback<T>* pbsc, BYTE* pBytes, DWORD dwSize);
  2059. public:
  2060. BEGIN_COM_MAP(CBindStatusCallback<T>)
  2061. COM_INTERFACE_ENTRY_IID(IID_IBindStatusCallback, IBindStatusCallbackImpl<T>)
  2062. END_COM_MAP()
  2063. CBindStatusCallback()
  2064. {
  2065. m_pT = NULL;
  2066. m_pFunc = NULL;
  2067. }
  2068. ~CBindStatusCallback()
  2069. {
  2070. ATLTRACE(_T("~CBindStatusCallback\n"));
  2071. }
  2072. STDMETHOD(OnStartBinding)(DWORD dwReserved, IBinding *pBinding)
  2073. {
  2074. ATLTRACE(_T("CBindStatusCallback::OnStartBinding\n"));
  2075. m_spBinding = pBinding;
  2076. return S_OK;
  2077. }
  2078. STDMETHOD(GetPriority)(LONG *pnPriority)
  2079. {
  2080. ATLTRACENOTIMPL(_T("CBindStatusCallback::GetPriority"));
  2081. }
  2082. STDMETHOD(OnLowResource)(DWORD reserved)
  2083. {
  2084. ATLTRACENOTIMPL(_T("CBindStatusCallback::OnLowResource"));
  2085. }
  2086. STDMETHOD(OnProgress)(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
  2087. {
  2088. ATLTRACENOTIMPL(_T("CBindStatusCallback::OnProgress"));
  2089. }
  2090. STDMETHOD(OnStopBinding)(HRESULT hresult, LPCWSTR szError)
  2091. {
  2092. ATLTRACE(_T("CBindStatusCallback::OnStopBinding\n"));
  2093. m_spBinding.Release();
  2094. m_spBindCtx.Release();
  2095. m_spMoniker.Release();
  2096. return S_OK;
  2097. }
  2098. STDMETHOD(GetBindInfo)(DWORD *pgrfBINDF, BINDINFO *pbindInfo)
  2099. {
  2100. ATLTRACE(_T("CBindStatusCallback::GetBindInfo\n"));
  2101. if (pbindInfo==NULL || pbindInfo->cbSize==0 || pgrfBINDF==NULL)
  2102. return E_INVALIDARG;
  2103. *pgrfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE |
  2104. BINDF_GETNEWESTVERSION | BINDF_NOWRITECACHE;
  2105. ULONG cbSize = pbindInfo->cbSize; // remember incoming cbSize
  2106. memset(pbindInfo, 0, cbSize); // zero out structure
  2107. pbindInfo->cbSize = cbSize; // restore cbSize
  2108. pbindInfo->dwBindVerb = BINDVERB_GET; // set verb
  2109. return S_OK;
  2110. }
  2111. STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
  2112. {
  2113. ATLTRACE(_T("CBindStatusCallback::OnDataAvailable\n"));
  2114. HRESULT hr = S_OK;
  2115. // Get the Stream passed
  2116. if (BSCF_FIRSTDATANOTIFICATION & grfBSCF)
  2117. {
  2118. if (!m_spStream && pstgmed->tymed == TYMED_ISTREAM)
  2119. m_spStream = pstgmed->pstm;
  2120. }
  2121. DWORD dwRead = dwSize - m_dwTotalRead; // Minimum amount available that hasn't been read
  2122. DWORD dwActuallyRead = 0; // Placeholder for amount read during this pull
  2123. // If there is some data to be read then go ahead and read them
  2124. if (m_spStream)
  2125. {
  2126. if (dwRead > 0)
  2127. {
  2128. BYTE* pBytes = NULL;
  2129. ATLTRY(pBytes = new BYTE[dwRead + 1]);
  2130. if (pBytes == NULL)
  2131. return S_FALSE;
  2132. hr = m_spStream->Read(pBytes, dwRead, &dwActuallyRead);
  2133. if (SUCCEEDED(hr))
  2134. {
  2135. pBytes[dwActuallyRead] = 0;
  2136. if (dwActuallyRead>0)
  2137. {
  2138. (m_pT->*m_pFunc)(this, pBytes, dwActuallyRead);
  2139. m_dwTotalRead += dwActuallyRead;
  2140. }
  2141. }
  2142. delete[] pBytes;
  2143. }
  2144. }
  2145. if (BSCF_LASTDATANOTIFICATION & grfBSCF)
  2146. m_spStream.Release();
  2147. return hr;
  2148. }
  2149. STDMETHOD(OnObjectAvailable)(REFIID riid, IUnknown *punk)
  2150. {
  2151. ATLTRACENOTIMPL(_T("CBindStatusCallback::OnObjectAvailable"));
  2152. }
  2153. HRESULT _StartAsyncDownload(BSTR bstrURL, IUnknown* pUnkContainer, BOOL bRelative)
  2154. {
  2155. m_dwTotalRead = 0;
  2156. m_dwAvailableToRead = 0;
  2157. HRESULT hr = S_OK;
  2158. CComQIPtr<IServiceProvider, &IID_IServiceProvider> spServiceProvider(pUnkContainer);
  2159. CComPtr<IBindHost> spBindHost;
  2160. CComPtr<IStream> spStream;
  2161. if (spServiceProvider)
  2162. spServiceProvider->QueryService(SID_IBindHost, IID_IBindHost, (void**)&spBindHost);
  2163. if (spBindHost == NULL)
  2164. {
  2165. if (bRelative)
  2166. return E_NOINTERFACE; // relative asked for, but no IBindHost
  2167. hr = CreateURLMoniker(NULL, bstrURL, &m_spMoniker);
  2168. if (SUCCEEDED(hr))
  2169. hr = CreateBindCtx(0, &m_spBindCtx);
  2170. if (SUCCEEDED(hr))
  2171. hr = RegisterBindStatusCallback(m_spBindCtx, reinterpret_cast<IBindStatusCallback*>(static_cast<IBindStatusCallbackImpl<T>*>(this)), 0, 0L);
  2172. else
  2173. m_spMoniker.Release();
  2174. if (SUCCEEDED(hr))
  2175. hr = m_spMoniker->BindToStorage(m_spBindCtx, 0, IID_IStream, (void**)&spStream);
  2176. }
  2177. else
  2178. {
  2179. hr = CreateBindCtx(0, &m_spBindCtx);
  2180. if (SUCCEEDED(hr))
  2181. hr = RegisterBindStatusCallback(m_spBindCtx, reinterpret_cast<IBindStatusCallback*>(static_cast<IBindStatusCallbackImpl<T>*>(this)), 0, 0L);
  2182. if (SUCCEEDED(hr))
  2183. {
  2184. if (bRelative)
  2185. hr = spBindHost->CreateMoniker(bstrURL, m_spBindCtx, &m_spMoniker, 0);
  2186. else
  2187. hr = CreateURLMoniker(NULL, bstrURL, &m_spMoniker);
  2188. }
  2189. if (SUCCEEDED(hr))
  2190. {
  2191. hr = spBindHost->MonikerBindToStorage(m_spMoniker, NULL, reinterpret_cast<IBindStatusCallback*>(static_cast<IBindStatusCallbackImpl<T>*>(this)), IID_IStream, (void**)&spStream);
  2192. ATLTRACE(_T("Bound"));
  2193. }
  2194. }
  2195. return hr;
  2196. }
  2197. HRESULT StartAsyncDownload(T* pT, ATL_PDATAAVAILABLE pFunc, BSTR bstrURL, IUnknown* pUnkContainer = NULL, BOOL bRelative = FALSE)
  2198. {
  2199. m_pT = pT;
  2200. m_pFunc = pFunc;
  2201. return _StartAsyncDownload(bstrURL, pUnkContainer, bRelative);
  2202. }
  2203. static HRESULT Download(T* pT, ATL_PDATAAVAILABLE pFunc, BSTR bstrURL, IUnknown* pUnkContainer = NULL, BOOL bRelative = FALSE)
  2204. {
  2205. CComObject<CBindStatusCallback<T> > *pbsc;
  2206. HRESULT hRes = CComObject<CBindStatusCallback<T> >::CreateInstance(&pbsc);
  2207. if (FAILED(hRes))
  2208. return hRes;
  2209. return pbsc->StartAsyncDownload(pT, pFunc, bstrURL, pUnkContainer, bRelative);
  2210. }
  2211. CComPtr<IMoniker> m_spMoniker;
  2212. CComPtr<IBindCtx> m_spBindCtx;
  2213. CComPtr<IBinding> m_spBinding;
  2214. CComPtr<IStream> m_spStream;
  2215. T* m_pT;
  2216. ATL_PDATAAVAILABLE m_pFunc;
  2217. DWORD m_dwTotalRead;
  2218. DWORD m_dwAvailableToRead;
  2219. };
  2220. #define IMPLEMENT_STOCKPROP(type, fname, pname, dispid) \
  2221. HRESULT STDMETHODCALLTYPE put_##fname(type pname) \
  2222. { \
  2223. T* pT = (T*) this; \
  2224. if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  2225. return S_FALSE; \
  2226. pT->m_##pname = pname; \
  2227. pT->m_bRequiresSave = TRUE; \
  2228. pT->FireOnChanged(dispid); \
  2229. pT->FireViewChange(); \
  2230. return S_OK; \
  2231. } \
  2232. HRESULT STDMETHODCALLTYPE get_##fname(type* p##pname) \
  2233. { \
  2234. T* pT = (T*) this; \
  2235. *p##pname = pT->m_##pname; \
  2236. return S_OK; \
  2237. }
  2238. #define IMPLEMENT_BOOL_STOCKPROP(fname, pname, dispid) \
  2239. HRESULT STDMETHODCALLTYPE put_##fname(VARIANT_BOOL pname) \
  2240. { \
  2241. T* pT = (T*) this; \
  2242. if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  2243. return S_FALSE; \
  2244. pT->m_##pname = pname; \
  2245. pT->m_bRequiresSave = TRUE; \
  2246. pT->FireOnChanged(dispid); \
  2247. pT->FireViewChange(); \
  2248. return S_OK; \
  2249. } \
  2250. HRESULT STDMETHODCALLTYPE get_##fname(VARIANT_BOOL* p##pname) \
  2251. { \
  2252. T* pT = (T*) this; \
  2253. *p##pname = pT->m_##pname ? VARIANT_TRUE : VARIANT_FALSE; \
  2254. return S_OK; \
  2255. }
  2256. #define IMPLEMENT_BSTR_STOCKPROP(fname, pname, dispid) \
  2257. HRESULT STDMETHODCALLTYPE put_##fname(BSTR pname) \
  2258. { \
  2259. T* pT = (T*) this; \
  2260. if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  2261. return S_FALSE; \
  2262. *(&(pT->m_##pname)) = SysAllocString(pname); \
  2263. pT->m_bRequiresSave = TRUE; \
  2264. pT->FireOnChanged(dispid); \
  2265. pT->FireViewChange(); \
  2266. return S_OK; \
  2267. } \
  2268. HRESULT STDMETHODCALLTYPE get_##fname(BSTR* p##pname) \
  2269. { \
  2270. T* pT = (T*) this; \
  2271. *p##pname = SysAllocString(pT->m_##pname); \
  2272. return S_OK; \
  2273. }
  2274. template < class T, class InterfaceName, const IID* piid, const GUID* plibid>
  2275. class ATL_NO_VTABLE CStockPropImpl : public IDispatchImpl< InterfaceName, piid, plibid >
  2276. {
  2277. public:
  2278. // Font
  2279. HRESULT STDMETHODCALLTYPE put_Font(IFontDisp* pFont)
  2280. {
  2281. T* pT = (T*) this;
  2282. if (pT->FireOnRequestEdit(DISPID_FONT) == S_FALSE)
  2283. return S_FALSE;
  2284. pT->m_pFont = 0;
  2285. if (pFont)
  2286. {
  2287. CComQIPtr<IFont, &IID_IFont> p(pFont);
  2288. if (p)
  2289. {
  2290. CComPtr<IFont> pFont;
  2291. p->Clone(&pFont);
  2292. if (pFont)
  2293. pFont->QueryInterface(IID_IFontDisp, (void**) &pT->m_pFont);
  2294. }
  2295. }
  2296. pT->m_bRequiresSave = TRUE;
  2297. pT->FireOnChanged(DISPID_FONT);
  2298. pT->FireViewChange();
  2299. return S_OK;
  2300. }
  2301. HRESULT STDMETHODCALLTYPE putref_Font(IFontDisp* pFont)
  2302. {
  2303. T* pT = (T*) this;
  2304. if (pT->FireOnRequestEdit(DISPID_FONT) == S_FALSE)
  2305. return S_FALSE;
  2306. pT->m_pFont = pFont;
  2307. pT->m_bRequiresSave = TRUE;
  2308. pT->FireOnChanged(DISPID_FONT);
  2309. pT->FireViewChange();
  2310. return S_OK;
  2311. }
  2312. HRESULT STDMETHODCALLTYPE get_Font(IFontDisp** ppFont)
  2313. {
  2314. T* pT = (T*) this;
  2315. *ppFont = pT->m_pFont;
  2316. if (*ppFont != NULL)
  2317. (*ppFont)->AddRef();
  2318. return S_OK;
  2319. }
  2320. // Picture
  2321. HRESULT STDMETHODCALLTYPE put_Picture(IPictureDisp* pPicture)
  2322. {
  2323. T* pT = (T*) this;
  2324. if (pT->FireOnRequestEdit(DISPID_PICTURE) == S_FALSE)
  2325. return S_FALSE;
  2326. pT->m_pPicture = 0;
  2327. if (pPicture)
  2328. {
  2329. CComQIPtr<IPersistStream, &IID_IPersistStream> p(pPicture);
  2330. if (p)
  2331. {
  2332. ULARGE_INTEGER l;
  2333. p->GetSizeMax(&l);
  2334. HGLOBAL hGlob = GlobalAlloc(GHND, l.LowPart);
  2335. if (hGlob)
  2336. {
  2337. CComPtr<IStream> spStream;
  2338. CreateStreamOnHGlobal(hGlob, TRUE, &spStream);
  2339. if (spStream)
  2340. {
  2341. if (SUCCEEDED(p->Save(spStream, FALSE)))
  2342. {
  2343. LARGE_INTEGER l;
  2344. l.QuadPart = 0;
  2345. spStream->Seek(l, STREAM_SEEK_SET, NULL);
  2346. OleLoadPicture(spStream, l.LowPart, FALSE, IID_IPictureDisp, (void**)&pT->m_pPicture);
  2347. }
  2348. spStream.Release();
  2349. }
  2350. GlobalFree(hGlob);
  2351. }
  2352. }
  2353. }
  2354. pT->m_bRequiresSave = TRUE;
  2355. pT->FireOnChanged(DISPID_PICTURE);
  2356. pT->FireViewChange();
  2357. return S_OK;
  2358. }
  2359. HRESULT STDMETHODCALLTYPE putref_Picture(IPictureDisp* pPicture)
  2360. {
  2361. T* pT = (T*) this;
  2362. if (pT->FireOnRequestEdit(DISPID_PICTURE) == S_FALSE)
  2363. return S_FALSE;
  2364. pT->m_pPicture = pPicture;
  2365. pT->m_bRequiresSave = TRUE;
  2366. pT->FireOnChanged(DISPID_PICTURE);
  2367. pT->FireViewChange();
  2368. return S_OK;
  2369. }
  2370. HRESULT STDMETHODCALLTYPE get_Picture(IPictureDisp** ppPicture)
  2371. {
  2372. T* pT = (T*) this;
  2373. *ppPicture = pT->m_pPicture;
  2374. if (*ppPicture != NULL)
  2375. (*ppPicture)->AddRef();
  2376. return S_OK;
  2377. }
  2378. // MouseIcon
  2379. HRESULT STDMETHODCALLTYPE put_MouseIcon(IPictureDisp* pPicture)
  2380. {
  2381. T* pT = (T*) this;
  2382. if (pT->FireOnRequestEdit(DISPID_MOUSEICON) == S_FALSE)
  2383. return S_FALSE;
  2384. pT->m_pMouseIcon = 0;
  2385. if (pPicture)
  2386. {
  2387. CComQIPtr<IPersistStream, &IID_IPersistStream> p(pPicture);
  2388. if (p)
  2389. {
  2390. ULARGE_INTEGER l;
  2391. p->GetSizeMax(&l);
  2392. HGLOBAL hGlob = GlobalAlloc(GHND, l.LowPart);
  2393. if (hGlob)
  2394. {
  2395. CComPtr<IStream> spStream;
  2396. CreateStreamOnHGlobal(hGlob, TRUE, &spStream);
  2397. if (spStream)
  2398. {
  2399. if (SUCCEEDED(p->Save(spStream, FALSE)))
  2400. {
  2401. LARGE_INTEGER l;
  2402. l.QuadPart = 0;
  2403. spStream->Seek(l, STREAM_SEEK_SET, NULL);
  2404. OleLoadPicture(spStream, l.LowPart, FALSE, IID_IPictureDisp, (void**)&pT->m_pMouseIcon);
  2405. }
  2406. spStream.Release();
  2407. }
  2408. GlobalFree(hGlob);
  2409. }
  2410. }
  2411. }
  2412. pT->m_bRequiresSave = TRUE;
  2413. pT->FireOnChanged(DISPID_MOUSEICON);
  2414. pT->FireViewChange();
  2415. return S_OK;
  2416. }
  2417. HRESULT STDMETHODCALLTYPE putref_MouseIcon(IPictureDisp* pPicture)
  2418. {
  2419. T* pT = (T*) this;
  2420. if (pT->FireOnRequestEdit(DISPID_MOUSEICON) == S_FALSE)
  2421. return S_FALSE;
  2422. pT->m_pMouseIcon = pPicture;
  2423. pT->m_bRequiresSave = TRUE;
  2424. pT->FireOnChanged(DISPID_MOUSEICON);
  2425. pT->FireViewChange();
  2426. return S_OK;
  2427. }
  2428. HRESULT STDMETHODCALLTYPE get_MouseIcon(IPictureDisp** ppPicture)
  2429. {
  2430. T* pT = (T*) this;
  2431. *ppPicture = pT->m_pMouseIcon;
  2432. if (*ppPicture != NULL)
  2433. (*ppPicture)->AddRef();
  2434. return S_OK;
  2435. }
  2436. IMPLEMENT_STOCKPROP(OLE_COLOR, BackColor, clrBackColor, DISPID_BACKCOLOR)
  2437. IMPLEMENT_STOCKPROP(OLE_COLOR, BorderColor, clrBorderColor, DISPID_BORDERCOLOR)
  2438. IMPLEMENT_STOCKPROP(OLE_COLOR, FillColor, clrFillColor, DISPID_FILLCOLOR)
  2439. IMPLEMENT_STOCKPROP(OLE_COLOR, ForeColor, clrForeColor, DISPID_FORECOLOR)
  2440. IMPLEMENT_BOOL_STOCKPROP(AutoSize, bAutoSize, DISPID_AUTOSIZE)
  2441. IMPLEMENT_BOOL_STOCKPROP(Valid, bValid, DISPID_VALID)
  2442. IMPLEMENT_BOOL_STOCKPROP(Enabled, bEnabled, DISPID_ENABLED)
  2443. IMPLEMENT_BOOL_STOCKPROP(TabStop, bTabStop, DISPID_TABSTOP)
  2444. IMPLEMENT_BOOL_STOCKPROP(BorderVisible, bBorderVisible, DISPID_BORDERVISIBLE)
  2445. IMPLEMENT_BSTR_STOCKPROP(Text, bstrText, DISPID_TEXT)
  2446. IMPLEMENT_BSTR_STOCKPROP(Caption, bstrCaption, DISPID_CAPTION)
  2447. HRESULT STDMETHODCALLTYPE put_Window(LONG /*hWnd*/)
  2448. {
  2449. return E_FAIL;
  2450. }
  2451. HRESULT STDMETHODCALLTYPE get_Window(LONG* phWnd)
  2452. {
  2453. T* pT = (T*) this;
  2454. *phWnd = (LONG)(LONG_PTR)pT->m_hWnd;
  2455. return S_OK;
  2456. }
  2457. IMPLEMENT_STOCKPROP(long, BackStyle, nBackStyle, DISPID_BACKSTYLE)
  2458. IMPLEMENT_STOCKPROP(long, BorderStyle, nBorderStyle, DISPID_BORDERSTYLE)
  2459. IMPLEMENT_STOCKPROP(long, BorderWidth, nBorderWidth, DISPID_BORDERWIDTH)
  2460. IMPLEMENT_STOCKPROP(long, DrawMode, nDrawMode, DISPID_DRAWMODE)
  2461. IMPLEMENT_STOCKPROP(long, DrawStyle, nDrawStyle, DISPID_DRAWSTYLE)
  2462. IMPLEMENT_STOCKPROP(long, DrawWidth, nDrawWidth, DISPID_DRAWWIDTH)
  2463. IMPLEMENT_STOCKPROP(long, FillStyle, nFillStyle, DISPID_FILLSTYLE)
  2464. IMPLEMENT_STOCKPROP(long, Appearance, nAppearance, DISPID_APPEARANCE)
  2465. IMPLEMENT_STOCKPROP(long, MousePointer, nMousePointer, DISPID_MOUSEPOINTER)
  2466. IMPLEMENT_STOCKPROP(long, ReadyState, nReadyState, DISPID_READYSTATE)
  2467. };
  2468. #ifndef ATL_NO_NAMESPACE
  2469. }; //namespace ATL
  2470. #endif
  2471. #endif // __ATLCTL_H__