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.

3400 lines
95 KiB

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