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

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