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.

3395 lines
92 KiB

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