Source code of Windows XP (NT5)
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.

4043 lines
108 KiB

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