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.

2103 lines
58 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) Microsoft Corporation, 1996 - 1999
  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 __ATL_SNAPIN_H__
  11. #define __ATL_SNAPIN_H__
  12. #include <mmc.h>
  13. #include <commctrl.h>
  14. #pragma comment(lib, "mmc.lib")
  15. #pragma comment(lib, "comctl32.lib")
  16. // MAM things which haven't made it into real atlsnap.h yet.
  17. #define TASKPAD_SUPPORT
  18. #define FIX_PROBLEM_WITH_PROPERTY_CHANGE_NOTIFICATION_HANDLES
  19. #define FIX_PROBLEM_WITH_DYNAMIC_CAST_ON_CSNAPINOBJECTROOT_NOT_WORKING
  20. #define FIX_PROBLEM_WITH_GET_RESULT_VIEW_TYPE_NULL_COOKIE
  21. template <class T, bool bAutoDelete = TRUE>
  22. class ATL_NO_VTABLE CSnapInPropertyPageImpl : public CDialogImplBase
  23. {
  24. public:
  25. PROPSHEETPAGE m_psp;
  26. #ifdef FIX_PROBLEM_WITH_PROPERTY_CHANGE_NOTIFICATION_HANDLES
  27. LONG_PTR m_hNotificationHandle;
  28. BOOL m_bOwnsNotificationHandle;
  29. #endif FIX_PROBLEM_WITH_PROPERTY_CHANGE_NOTIFICATION_HANDLES
  30. operator PROPSHEETPAGE*() { return &m_psp; }
  31. // Construction
  32. #ifdef FIX_PROBLEM_WITH_PROPERTY_CHANGE_NOTIFICATION_HANDLES
  33. CSnapInPropertyPageImpl(LONG_PTR hNotificationHandle, LPCTSTR lpszTitle = NULL, BOOL bOwnsNotificationHandle = FALSE)
  34. #else
  35. CSnapInPropertyPageImpl(LPCTSTR lpszTitle = NULL)
  36. #endif // FIX_PROBLEM_WITH_PROPERTY_CHANGE_NOTIFICATION_HANDLES
  37. {
  38. // initialize PROPSHEETPAGE struct
  39. memset(&m_psp, 0, sizeof(PROPSHEETPAGE));
  40. m_psp.dwSize = sizeof(PROPSHEETPAGE);
  41. m_psp.dwFlags = PSP_USECALLBACK;
  42. m_psp.hInstance = _Module.GetResourceInstance();
  43. m_psp.pszTemplate = MAKEINTRESOURCE(T::IDD);
  44. m_psp.pfnDlgProc = T::StartDialogProc;
  45. m_psp.pfnCallback = T::PropPageCallback;
  46. m_psp.lParam = (LPARAM)this;
  47. if(lpszTitle != NULL)
  48. {
  49. m_psp.pszTitle = lpszTitle;
  50. m_psp.dwFlags |= PSP_USETITLE;
  51. }
  52. #ifdef FIX_PROBLEM_WITH_PROPERTY_CHANGE_NOTIFICATION_HANDLES
  53. m_hNotificationHandle = hNotificationHandle;
  54. m_bOwnsNotificationHandle = bOwnsNotificationHandle;
  55. #endif //FIX_PROBLEM_WITH_PROPERTY_CHANGE_NOTIFICATION_HANDLES
  56. }
  57. void SetTitles(LPCWSTR szTitle, LPCWSTR szSubtitle)
  58. {
  59. m_psp.dwFlags |= PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  60. m_psp.pszHeaderTitle = szTitle;
  61. m_psp.pszHeaderSubTitle = szSubtitle;
  62. };
  63. #ifdef FIX_PROBLEM_WITH_PROPERTY_CHANGE_NOTIFICATION_HANDLES
  64. ~CSnapInPropertyPageImpl()
  65. {
  66. if( m_bOwnsNotificationHandle )
  67. {
  68. // The MMC docs specify that this handle should only be freed once.
  69. // For this reason, we have the bOwnsNotificationHandle flag which
  70. // should only be set for one property page.
  71. // We only free the handle in the destructor of the page
  72. // that has been designated as the "owner".
  73. MMCFreeNotifyHandle( m_hNotificationHandle );
  74. }
  75. }
  76. HRESULT PropertyChangeNotify( LPARAM param )
  77. {
  78. return MMCPropertyChangeNotify( m_hNotificationHandle, param );
  79. }
  80. #endif //FIX_PROBLEM_WITH_PROPERTY_CHANGE_NOTIFICATION_HANDLES
  81. static UINT CALLBACK PropPageCallback(HWND hWnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
  82. {
  83. ATLASSERT(hWnd == NULL);
  84. if(uMsg == PSPCB_CREATE)
  85. {
  86. CDialogImplBase* pPage = (CDialogImplBase*)ppsp->lParam;
  87. _Module.AddCreateWndData(&pPage->m_thunk.cd, pPage);
  88. }
  89. if (bAutoDelete && uMsg == PSPCB_RELEASE)
  90. {
  91. T* pPage = (T*)ppsp->lParam;
  92. delete pPage;
  93. }
  94. return 1;
  95. }
  96. HPROPSHEETPAGE Create()
  97. {
  98. return ::CreatePropertySheetPage(&m_psp);
  99. }
  100. BOOL EndDialog(int)
  101. {
  102. // do nothing here, calling ::EndDialog will close the whole sheet
  103. ATLASSERT(FALSE);
  104. return FALSE;
  105. }
  106. // Operations
  107. void CancelToClose()
  108. {
  109. ATLASSERT(::IsWindow(m_hWnd));
  110. ATLASSERT(GetParent() != NULL);
  111. ::SendMessage(GetParent(), PSM_CANCELTOCLOSE, 0, 0L);
  112. }
  113. void SetModified(BOOL bChanged = TRUE)
  114. {
  115. ATLASSERT(::IsWindow(m_hWnd));
  116. ATLASSERT(GetParent() != NULL);
  117. if(bChanged)
  118. ::SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0L);
  119. else
  120. ::SendMessage(GetParent(), PSM_UNCHANGED, (WPARAM)m_hWnd, 0L);
  121. }
  122. LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam)
  123. {
  124. ATLASSERT(::IsWindow(m_hWnd));
  125. ATLASSERT(GetParent() != NULL);
  126. return ::SendMessage(GetParent(), PSM_QUERYSIBLINGS, wParam, lParam);
  127. }
  128. BEGIN_MSG_MAP(CSnapInPropertyPageImpl< T >)
  129. MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
  130. END_MSG_MAP()
  131. // Message handler
  132. LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  133. {
  134. ATLASSERT(::IsWindow(m_hWnd));
  135. NMHDR* pNMHDR = (NMHDR*)lParam;
  136. // don't handle messages not from the page/sheet itself
  137. if(pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd))
  138. {
  139. bHandled = FALSE;
  140. return 1;
  141. }
  142. T* pT = (T*)this;
  143. LRESULT lResult = 0;
  144. // handle default
  145. switch(pNMHDR->code)
  146. {
  147. case PSN_SETACTIVE:
  148. lResult = pT->OnSetActive() ? 0 : -1;
  149. break;
  150. case PSN_KILLACTIVE:
  151. lResult = !pT->OnKillActive();
  152. break;
  153. case PSN_APPLY:
  154. lResult = pT->OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE;
  155. break;
  156. case PSN_RESET:
  157. pT->OnReset();
  158. break;
  159. case PSN_QUERYCANCEL:
  160. lResult = !pT->OnQueryCancel();
  161. break;
  162. case PSN_WIZNEXT:
  163. // changed, since the orginal one doesn't work when jump to a different page
  164. {
  165. LRESULT l = pT->OnWizardNext();
  166. switch(l)
  167. {
  168. case TRUE:
  169. lResult = 0;
  170. break;
  171. case FALSE:
  172. lResult = -1;
  173. break;
  174. default:
  175. lResult = l;
  176. break;
  177. }
  178. }
  179. break;
  180. case PSN_WIZBACK:
  181. // changed, since the orginal one doesn't work when jump to a different page
  182. {
  183. LRESULT l = pT->OnWizardBack();
  184. switch(l)
  185. {
  186. case TRUE:
  187. lResult = 0;
  188. break;
  189. case FALSE:
  190. lResult = -1;
  191. break;
  192. default:
  193. lResult = l;
  194. break;
  195. }
  196. }
  197. break;
  198. case PSN_WIZFINISH:
  199. lResult = !pT->OnWizardFinish();
  200. break;
  201. case PSN_HELP:
  202. lResult = pT->OnHelp();
  203. break;
  204. default:
  205. bHandled = FALSE; // not handled
  206. }
  207. return lResult;
  208. }
  209. // Overridables
  210. BOOL OnSetActive()
  211. {
  212. return TRUE;
  213. }
  214. BOOL OnKillActive()
  215. {
  216. return TRUE;
  217. }
  218. BOOL OnApply()
  219. {
  220. return TRUE;
  221. }
  222. void OnReset()
  223. {
  224. }
  225. BOOL OnQueryCancel()
  226. {
  227. return TRUE; // ok to cancel
  228. }
  229. BOOL OnWizardBack()
  230. {
  231. return TRUE;
  232. }
  233. BOOL OnWizardNext()
  234. {
  235. return TRUE;
  236. }
  237. BOOL OnWizardFinish()
  238. {
  239. return TRUE;
  240. }
  241. BOOL OnHelp()
  242. {
  243. return TRUE;
  244. }
  245. };
  246. #if _ATL_VER < 0x0300
  247. // intended for small number of simple types or pointers
  248. template <class TKey, class TVal>
  249. class CSimpleMap
  250. {
  251. public:
  252. TKey* m_aKey;
  253. TVal* m_aVal;
  254. int m_nSize;
  255. // Construction/destruction
  256. CSimpleMap() : m_aKey(NULL), m_aVal(NULL), m_nSize(0)
  257. { }
  258. ~CSimpleMap()
  259. {
  260. RemoveAll();
  261. }
  262. // Operations
  263. int GetSize() const
  264. {
  265. return m_nSize;
  266. }
  267. BOOL Add(TKey key, TVal val)
  268. {
  269. TKey* pKey;
  270. pKey = (TKey*)realloc(m_aKey, (m_nSize + 1) * sizeof(TKey));
  271. if(pKey == NULL)
  272. return FALSE;
  273. m_aKey = pKey;
  274. TVal* pVal;
  275. pVal = (TVal*)realloc(m_aVal, (m_nSize + 1) * sizeof(TVal));
  276. if(pVal == NULL)
  277. return FALSE;
  278. m_aVal = pVal;
  279. m_nSize++;
  280. SetAtIndex(m_nSize - 1, key, val);
  281. return TRUE;
  282. }
  283. BOOL Remove(TKey key)
  284. {
  285. int nIndex = FindKey(key);
  286. if(nIndex == -1)
  287. return FALSE;
  288. if(nIndex != (m_nSize - 1))
  289. {
  290. memmove((void*)&m_aKey[nIndex], (void*)&m_aKey[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TKey));
  291. memmove((void*)&m_aVal[nIndex], (void*)&m_aVal[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TVal));
  292. }
  293. TKey* pKey;
  294. pKey = (TKey*)realloc(m_aKey, (m_nSize - 1) * sizeof(TKey));
  295. if(pKey != NULL || m_nSize == 1)
  296. m_aKey = pKey;
  297. TVal* pVal;
  298. pVal = (TVal*)realloc(m_aVal, (m_nSize - 1) * sizeof(TVal));
  299. if(pVal != NULL || m_nSize == 1)
  300. m_aVal = pVal;
  301. m_nSize--;
  302. return TRUE;
  303. }
  304. void RemoveAll()
  305. {
  306. if(m_nSize > 0)
  307. {
  308. free(m_aKey);
  309. free(m_aVal);
  310. m_aKey = NULL;
  311. m_aVal = NULL;
  312. m_nSize = 0;
  313. }
  314. }
  315. BOOL SetAt(TKey key, TVal val)
  316. {
  317. int nIndex = FindKey(key);
  318. if(nIndex == -1)
  319. return FALSE;
  320. SetAtIndex(nIndex, key, val);
  321. return TRUE;
  322. }
  323. TVal Lookup(TKey key) const
  324. {
  325. int nIndex = FindKey(key);
  326. if(nIndex == -1)
  327. return NULL; // must be able to convert
  328. return GetValueAt(nIndex);
  329. }
  330. TKey ReverseLookup(TVal val) const
  331. {
  332. int nIndex = FindVal(val);
  333. if(nIndex == -1)
  334. return NULL; // must be able to convert
  335. return GetKeyAt(nIndex);
  336. }
  337. TKey& GetKeyAt(int nIndex) const
  338. {
  339. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  340. return m_aKey[nIndex];
  341. }
  342. TVal& GetValueAt(int nIndex) const
  343. {
  344. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  345. return m_aVal[nIndex];
  346. }
  347. // Implementation
  348. void SetAtIndex(int nIndex, TKey& key, TVal& val)
  349. {
  350. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  351. m_aKey[nIndex] = key;
  352. m_aVal[nIndex] = val;
  353. }
  354. int FindKey(TKey& key) const
  355. {
  356. for(int i = 0; i < m_nSize; i++)
  357. {
  358. if(m_aKey[i] == key)
  359. return i;
  360. }
  361. return -1; // not found
  362. }
  363. int FindVal(TVal& val) const
  364. {
  365. for(int i = 0; i < m_nSize; i++)
  366. {
  367. if(m_aVal[i] == val)
  368. return i;
  369. }
  370. return -1; // not found
  371. }
  372. };
  373. #endif
  374. class CSnapInItem;
  375. class CSnapInObjectRootBase;
  376. class CObjectData
  377. {
  378. public:
  379. CSnapInItem* m_pItem;
  380. DATA_OBJECT_TYPES m_type;
  381. };
  382. class ATL_NO_VTABLE CSnapInItem
  383. {
  384. public:
  385. CSnapInItem(unsigned int helpIndex = 0)
  386. :m_helpIndex(helpIndex)
  387. {
  388. }
  389. virtual ~CSnapInItem()
  390. {
  391. }
  392. STDMETHOD(Notify)(MMC_NOTIFY_TYPE event,
  393. LPARAM arg,
  394. LPARAM param,
  395. IComponentData* pComponentData,
  396. IComponent* pComponent,
  397. DATA_OBJECT_TYPES type) = 0;
  398. STDMETHOD(GetScopePaneInfo)(SCOPEDATAITEM *pScopeDataItem) = 0;
  399. STDMETHOD(GetResultViewType)(LPOLESTR *ppViewType,
  400. long *pViewOptions) = 0;
  401. STDMETHOD(GetResultPaneInfo)(RESULTDATAITEM *pResultDataItem) = 0;
  402. STDMETHOD(AddMenuItems)(LPCONTEXTMENUCALLBACK piCallback,
  403. long *pInsertionAllowed,
  404. DATA_OBJECT_TYPES type) = 0;
  405. STDMETHOD(Command)(long lCommandID,
  406. CSnapInObjectRootBase* pObj,
  407. DATA_OBJECT_TYPES type) = 0;
  408. STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider,
  409. LONG_PTR handle,
  410. IUnknown* pUnk,
  411. DATA_OBJECT_TYPES type) = 0;
  412. STDMETHOD(QueryPagesFor)(DATA_OBJECT_TYPES type) = 0;
  413. STDMETHOD(SetControlbar)(IControlbar *pControlbar,
  414. IExtendControlbar *pExtendControlbar,
  415. CSimpleMap<UINT, IUnknown*>* pToolbarMap) = 0;
  416. STDMETHOD(ControlbarNotify)(IControlbar *pControlbar,
  417. IExtendControlbar *pExtendControlbar,
  418. CSimpleMap<UINT, IUnknown*>* pToolbarMap,
  419. MMC_NOTIFY_TYPE event,
  420. LPARAM arg,
  421. LPARAM param,
  422. CSnapInObjectRootBase* pObj,
  423. DATA_OBJECT_TYPES type) = 0;
  424. STDMETHOD(GetScopeData)(SCOPEDATAITEM * *pScopeDataItem) = 0;
  425. STDMETHOD(GetResultData)(RESULTDATAITEM * *pResultDataItem) = 0;
  426. STDMETHOD(FillData)(CLIPFORMAT cf,
  427. LPSTREAM pStream) = 0;
  428. virtual void InitDataClass(IDataObject* pDataObject, CSnapInItem* pDefault)
  429. {
  430. _ASSERTE(0 && "Override this function in derived class");
  431. }
  432. static HRESULT GetDataClass(IDataObject* pDataObj, CSnapInItem** ppItem, DATA_OBJECT_TYPES* pType)
  433. {
  434. if (ppItem == NULL)
  435. return E_POINTER;
  436. if (pType == NULL)
  437. return E_POINTER;
  438. if (IS_SPECIAL_DATAOBJECT(pDataObj))
  439. return E_NOTIMPL;
  440. *ppItem = NULL;
  441. *pType = CCT_UNINITIALIZED;
  442. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  443. FORMATETC formatetc = { m_CCF_SNAPIN_GETOBJECTDATA,
  444. NULL,
  445. DVASPECT_CONTENT,
  446. -1,
  447. TYMED_HGLOBAL
  448. };
  449. stgmedium.hGlobal = GlobalAlloc(0, sizeof(CObjectData));
  450. if (stgmedium.hGlobal == NULL)
  451. return E_OUTOFMEMORY;
  452. HRESULT hr = pDataObj->GetDataHere(&formatetc, &stgmedium);
  453. if (SUCCEEDED(hr))
  454. {
  455. CObjectData* pData = (CObjectData*)stgmedium.hGlobal;
  456. *ppItem = pData->m_pItem;
  457. *pType = pData->m_type;
  458. }
  459. GlobalFree(stgmedium.hGlobal);
  460. return hr;
  461. }
  462. #ifdef TASKPAD_SUPPORT
  463. STDMETHOD(TaskNotify)(
  464. IDataObject * pDataObject
  465. , VARIANT * pvarg
  466. , VARIANT * pvparam
  467. ) = 0;
  468. STDMETHOD(EnumTasks)(
  469. IDataObject * pDataObject
  470. , BSTR szTaskGroup
  471. , IEnumTASK** ppEnumTASK
  472. ) = 0;
  473. #endif // TASKPAD_SUPPORT
  474. virtual HRESULT STDMETHODCALLTYPE GetDataObject(IDataObject** pDataObj, DATA_OBJECT_TYPES type) = 0;
  475. static void Init()
  476. {
  477. m_CCF_NODETYPE = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_NODETYPE"));
  478. m_CCF_SZNODETYPE = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_SZNODETYPE"));
  479. m_CCF_DISPLAY_NAME = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_DISPLAY_NAME"));
  480. m_CCF_SNAPIN_CLASSID = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_SNAPIN_CLASSID"));
  481. m_CCF_SNAPIN_GETOBJECTDATA = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_GETOBJECTDATA"));
  482. m_CCF_MMC_MULTISELECT_DATAOBJECT = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_MMC_MULTISELECT_DATAOBJECT"));
  483. }
  484. public:
  485. static CLIPFORMAT m_CCF_NODETYPE;
  486. static CLIPFORMAT m_CCF_SZNODETYPE;
  487. static CLIPFORMAT m_CCF_DISPLAY_NAME;
  488. static CLIPFORMAT m_CCF_SNAPIN_CLASSID;
  489. static CLIPFORMAT m_CCF_SNAPIN_GETOBJECTDATA;
  490. static CLIPFORMAT m_CCF_MMC_MULTISELECT_DATAOBJECT;
  491. // IAS: Added to store some information about which help file to use
  492. unsigned int m_helpIndex;
  493. };
  494. class CSnapInObjectRootBase
  495. {
  496. public:
  497. CComPtr <IControlbar> m_spControlbar;
  498. CSimpleMap <UINT, IUnknown*> m_toolbarMap;
  499. const int m_ntype;
  500. CSnapInObjectRootBase(int n = 0) : m_ntype(n)
  501. {
  502. }
  503. HRESULT GetDataClass(IDataObject* pDataObject, CSnapInItem** ppItem, DATA_OBJECT_TYPES* pType)
  504. {
  505. return CSnapInItem::GetDataClass(pDataObject, ppItem, pType);
  506. }
  507. #ifdef FIX_PROBLEM_WITH_DYNAMIC_CAST_ON_CSNAPINOBJECTROOT_NOT_WORKING
  508. // Need at least one virtual method, or compiler does not generate a vtable
  509. virtual ~CSnapInObjectRootBase()
  510. {
  511. }
  512. #endif FIX_PROBLEM_WITH_DYNAMIC_CAST_ON_CSNAPINOBJECTROOT_NOT_WORKING
  513. };
  514. template <int n, class ComponentData>
  515. class CSnapInObjectRoot : public CSnapInObjectRootBase
  516. {
  517. public :
  518. CSnapInObjectRoot() : CSnapInObjectRootBase(n)
  519. {
  520. m_pComponentData = NULL;
  521. }
  522. ComponentData* m_pComponentData;
  523. };
  524. #define EXTENSION_SNAPIN_DATACLASS(dataClass) dataClass m_##dataClass;
  525. #define BEGIN_EXTENSION_SNAPIN_NODEINFO_MAP(classname) \
  526. HRESULT GetDataClass(IDataObject* pDataObject, CSnapInItem** ppItem, DATA_OBJECT_TYPES* pType) \
  527. { \
  528. if (ppItem == NULL) \
  529. return E_POINTER; \
  530. if (pType == NULL) \
  531. return E_POINTER; \
  532. if (IS_SPECIAL_DATAOBJECT(pDataObject)) \
  533. return E_NOTIMPL; \
  534. \
  535. *ppItem = NULL; \
  536. \
  537. *pType = CCT_UNINITIALIZED; \
  538. \
  539. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL }; \
  540. FORMATETC formatetc = { CSnapInItem::m_CCF_NODETYPE, \
  541. NULL, \
  542. DVASPECT_CONTENT, \
  543. -1, \
  544. TYMED_HGLOBAL \
  545. }; \
  546. \
  547. stgmedium.hGlobal = GlobalAlloc(0, sizeof(GUID)); \
  548. if (stgmedium.hGlobal == NULL) \
  549. return E_OUTOFMEMORY; \
  550. \
  551. HRESULT hr = pDataObject->GetDataHere(&formatetc, &stgmedium); \
  552. if (FAILED(hr)) \
  553. { \
  554. GlobalFree(stgmedium.hGlobal); \
  555. return hr; \
  556. } \
  557. \
  558. GUID guid; \
  559. memcpy(&guid, stgmedium.hGlobal, sizeof(GUID)); \
  560. \
  561. GlobalFree(stgmedium.hGlobal); \
  562. hr = S_OK;
  563. #define EXTENSION_SNAPIN_NODEINFO_ENTRY(dataClass) \
  564. if (IsEqualGUID(guid, *(GUID*)m_##dataClass.GetNodeType())) \
  565. { \
  566. *ppItem = m_##dataClass.GetExtNodeObject(pDataObject, &m_##dataClass); \
  567. _ASSERTE(*ppItem != NULL); \
  568. (*ppItem)->InitDataClass(pDataObject, &m_##dataClass); \
  569. return hr; \
  570. }
  571. #define END_EXTENSION_SNAPIN_NODEINFO_MAP() \
  572. return CSnapInItem::GetDataClass(pDataObject, ppItem, pType); \
  573. };
  574. class ATL_NO_VTABLE CSnapInDataObjectImpl : public IDataObject,
  575. public CComObjectRoot
  576. {
  577. public:
  578. BEGIN_COM_MAP(CSnapInDataObjectImpl)
  579. COM_INTERFACE_ENTRY(IDataObject)
  580. END_COM_MAP()
  581. STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
  582. {
  583. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::GetData\n"));
  584. }
  585. STDMETHOD(GetDataHere)(FORMATETC* pformatetc, STGMEDIUM* pmedium)
  586. {
  587. ATLTRACE(_T("SnapInDataObjectImpl::GetDataHere\n"));
  588. if (pmedium == NULL)
  589. return E_POINTER;
  590. HRESULT hr = DV_E_TYMED;
  591. // Make sure the type medium is HGLOBAL
  592. if (pmedium->tymed == TYMED_HGLOBAL)
  593. {
  594. // Create the stream on the hGlobal passed in
  595. CComPtr<IStream> spStream;
  596. hr = CreateStreamOnHGlobal(pmedium->hGlobal, FALSE, &spStream);
  597. if (SUCCEEDED(hr))
  598. if (pformatetc->cfFormat == CSnapInItem::m_CCF_SNAPIN_GETOBJECTDATA)
  599. {
  600. hr = DV_E_CLIPFORMAT;
  601. ULONG uWritten;
  602. hr = spStream->Write(&m_objectData, sizeof(CObjectData), &uWritten);
  603. }
  604. else
  605. hr = m_objectData.m_pItem->FillData(pformatetc->cfFormat, spStream);
  606. }
  607. return hr;
  608. }
  609. STDMETHOD(QueryGetData)(FORMATETC* /* pformatetc */)
  610. {
  611. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::QueryGetData\n"));
  612. }
  613. STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */)
  614. {
  615. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::GetCanonicalFormatEtc\n"));
  616. }
  617. STDMETHOD(SetData)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */)
  618. {
  619. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetData\n"));
  620. }
  621. STDMETHOD(EnumFormatEtc)(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */)
  622. {
  623. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::EnumFormatEtc\n"));
  624. }
  625. STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink,
  626. DWORD *pdwConnection)
  627. {
  628. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetData\n"));
  629. }
  630. STDMETHOD(DUnadvise)(DWORD dwConnection)
  631. {
  632. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetDatan\n"));
  633. }
  634. STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise)
  635. {
  636. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetData\n"));
  637. }
  638. CObjectData m_objectData;
  639. };
  640. template <class T, class Component>
  641. class ATL_NO_VTABLE IComponentDataImpl : public IComponentData
  642. {
  643. public :
  644. IComponentDataImpl()
  645. {
  646. m_pNode = NULL;
  647. }
  648. STDMETHOD(Initialize)(LPUNKNOWN pUnknown)
  649. {
  650. ATLTRACE(_T("IComponentDataImpl::Initialize\n"));
  651. HRESULT hr = E_POINTER;
  652. ATLASSERT(pUnknown != NULL);
  653. if (pUnknown == NULL)
  654. ATLTRACE(_T("IComponentData::Initialize called with pUnknown == NULL\n"));
  655. else
  656. {
  657. hr = pUnknown->QueryInterface(IID_IConsole, (void**)&m_spConsole);
  658. if (FAILED(hr))
  659. ATLTRACE(_T("QI for IConsole failed\n"));
  660. }
  661. return hr;
  662. }
  663. STDMETHOD(CreateComponent)(LPCOMPONENT *ppComponent)
  664. {
  665. ATLTRACE(_T("IComponentDataImpl::CreateComponent\n"));
  666. HRESULT hr = E_POINTER;
  667. ATLASSERT(ppComponent != NULL);
  668. if (ppComponent == NULL)
  669. ATLTRACE(_T("IComponentData::CreateComponent called with ppComponent == NULL\n"));
  670. else
  671. {
  672. *ppComponent = NULL;
  673. CComObject< Component >* pComponent;
  674. hr = CComObject< Component >::CreateInstance(&pComponent);
  675. ATLASSERT(SUCCEEDED(hr));
  676. if (FAILED(hr))
  677. ATLTRACE(_T("IComponentData::CreateComponent : Could not create IComponent object\n"));
  678. else
  679. {
  680. pComponent->m_pComponentData = static_cast<T*>(this);
  681. hr = pComponent->QueryInterface(IID_IComponent, (void**)ppComponent);
  682. }
  683. }
  684. return hr;
  685. }
  686. STDMETHOD(Notify)(
  687. LPDATAOBJECT lpDataObject,
  688. MMC_NOTIFY_TYPE event,
  689. LPARAM arg,
  690. LPARAM param)
  691. {
  692. ATLTRACE(_T("IComponentDataImpl::Notify\n"));
  693. HRESULT hr = E_POINTER;
  694. ATLASSERT(lpDataObject != NULL);
  695. if (lpDataObject == NULL)
  696. ATLTRACE(_T("IComponentData::Notify called with lpDataObject == NULL\n"));
  697. else
  698. {
  699. T* pT = static_cast<T*>(this);
  700. CSnapInItem* pItem;
  701. DATA_OBJECT_TYPES type;
  702. hr = pT->m_pComponentData->GetDataClass(lpDataObject, &pItem, &type);
  703. ATLASSERT(SUCCEEDED(hr));
  704. if (SUCCEEDED(hr))
  705. hr = pItem->Notify(event, arg, param, pT, NULL, type);
  706. }
  707. return hr;
  708. }
  709. STDMETHOD(Destroy)(void)
  710. {
  711. ATLTRACE(_T("IComponentDataImpl::Destroy\n"));
  712. T* pT = static_cast<T*>(this);
  713. if (pT->m_spControlbar != NULL)
  714. {
  715. int n = pT->m_toolbarMap.GetSize();
  716. for (int i = 0; i < n; i++)
  717. {
  718. IToolbar* pToolbar = (IToolbar*)pT->m_toolbarMap.GetValueAt(i);
  719. if (pToolbar != NULL)
  720. {
  721. pT->m_spControlbar->Detach(pToolbar);
  722. pToolbar->Release();
  723. }
  724. }
  725. }
  726. pT->m_toolbarMap.RemoveAll();
  727. m_spConsole.Release();
  728. return S_OK;
  729. }
  730. STDMETHOD(QueryDataObject)(MMC_COOKIE cookie,
  731. DATA_OBJECT_TYPES type,
  732. LPDATAOBJECT *ppDataObject)
  733. {
  734. ATLTRACE(_T("IComponentDataImpl::QueryDataObject\n"));
  735. HRESULT hr = E_POINTER;
  736. ATLASSERT(ppDataObject != NULL);
  737. if (ppDataObject == NULL)
  738. ATLTRACE(_T("IComponentData::QueryDataObject called with ppDataObject == NULL\n"));
  739. else
  740. {
  741. *ppDataObject = NULL;
  742. CSnapInItem* pItem = (CSnapInItem*) cookie;
  743. if (cookie == NULL)
  744. pItem = m_pNode;
  745. hr = pItem->GetDataObject(ppDataObject, type);
  746. }
  747. return hr;
  748. }
  749. STDMETHOD(GetDisplayInfo)(SCOPEDATAITEM *pScopeDataItem)
  750. {
  751. ATLTRACE(_T("IComponentDataImpl::GetDisplayInfo\n"));
  752. HRESULT hr = E_POINTER;
  753. ATLASSERT(pScopeDataItem != NULL);
  754. if (pScopeDataItem == NULL)
  755. ATLTRACE(_T("IComponentData::GetDisplayInfo called with pScopeDataItem == NULL\n"));
  756. else
  757. {
  758. CSnapInItem* pItem= (CSnapInItem*) pScopeDataItem->lParam;
  759. if (pItem == NULL)
  760. pItem = m_pNode;
  761. hr = E_UNEXPECTED;
  762. if (pItem != NULL)
  763. hr = pItem->GetScopePaneInfo(pScopeDataItem);
  764. }
  765. return hr;
  766. }
  767. STDMETHOD(CompareObjects)(LPDATAOBJECT lpDataObjectA,
  768. LPDATAOBJECT lpDataObjectB)
  769. {
  770. ATLTRACENOTIMPL(_T("IComponentDataImpl::CompareObjects\n"));
  771. }
  772. CComPtr<IConsole> m_spConsole;
  773. CSnapInItem* m_pNode;
  774. };
  775. template <class T>
  776. class ATL_NO_VTABLE IComponentImpl : public IComponent
  777. {
  778. public:
  779. STDMETHOD(Initialize)(LPCONSOLE lpConsole)
  780. {
  781. ATLTRACE(_T("IComponentImpl::Initialize\n"));
  782. HRESULT hr = E_POINTER;
  783. ATLASSERT(lpConsole != NULL);
  784. if (lpConsole == NULL)
  785. ATLTRACE(_T("lpConsole is NULL\n"));
  786. else
  787. {
  788. m_spConsole = lpConsole;
  789. CComPtr<IHeaderCtrl> spHeaderCtrl;
  790. hr = m_spConsole->QueryInterface(IID_IHeaderCtrl, (void**)&spHeaderCtrl);
  791. if (FAILED(hr))
  792. ATLTRACE(_T("QI for IHeaderCtrl failed\n"));
  793. else
  794. {
  795. hr = m_spConsole->SetHeader(spHeaderCtrl);
  796. if (FAILED(hr))
  797. ATLTRACE(_T("IConsole::SetHeader failed (HRESULT = %x)\n"), hr);
  798. }
  799. }
  800. return hr;
  801. }
  802. STDMETHOD(Notify)(LPDATAOBJECT lpDataObject,
  803. MMC_NOTIFY_TYPE event,
  804. LPARAM arg,
  805. LPARAM param);
  806. STDMETHOD(Destroy)(MMC_COOKIE cookie)
  807. {
  808. ATLTRACE(_T("IComponentImpl::Destroy\n"));
  809. T* pT = static_cast<T*>(this);
  810. if (pT->m_spControlbar != NULL)
  811. {
  812. int n = pT->m_toolbarMap.GetSize();
  813. for (int i = 0; i < n; i++)
  814. {
  815. IToolbar* pToolbar = (IToolbar*)pT->m_toolbarMap.GetValueAt(i);
  816. if (pToolbar != NULL)
  817. {
  818. pT->m_spControlbar->Detach(pToolbar);
  819. pToolbar->Release();
  820. }
  821. }
  822. }
  823. pT->m_toolbarMap.RemoveAll();
  824. m_spConsole->SetHeader(NULL);
  825. m_spConsole.Release();
  826. return S_OK;
  827. }
  828. STDMETHOD(QueryDataObject)(MMC_COOKIE cookie,
  829. DATA_OBJECT_TYPES type,
  830. LPDATAOBJECT *ppDataObject)
  831. {
  832. ATLTRACE(_T("IComponentImpl::QueryDataObject\n"));
  833. ATLASSERT(ppDataObject != NULL);
  834. if (ppDataObject == NULL)
  835. {
  836. ATLTRACE(_T("IComponent::QueryDataObject called with ppDataObject==NULL \n"));
  837. return E_POINTER;
  838. }
  839. if (cookie == NULL)
  840. {
  841. ATLTRACE(_T("IComponent::QueryDataObject called with cookie==NULL \n"));
  842. return E_UNEXPECTED;
  843. }
  844. *ppDataObject = NULL;
  845. if (cookie == MMC_MULTI_SELECT_COOKIE)
  846. {
  847. ATLTRACE(_T("Override QueryDataObject to handle multiselect\n"));
  848. return E_UNEXPECTED;
  849. }
  850. CSnapInItem* pItem = (CSnapInItem*) cookie;
  851. return pItem->GetDataObject(ppDataObject, type);
  852. }
  853. STDMETHOD(GetResultViewType)(MMC_COOKIE cookie,
  854. LPOLESTR *ppViewType,
  855. long *pViewOptions)
  856. {
  857. ATLTRACE(_T("IComponentImpl::GetResultViewType\n"));
  858. if (cookie == NULL)
  859. {
  860. #ifdef FIX_PROBLEM_WITH_GET_RESULT_VIEW_TYPE_NULL_COOKIE
  861. T* pT = static_cast<T*>(this);
  862. // We are being asked about our root node.
  863. _ASSERTE( pT->m_pComponentData!= NULL );
  864. _ASSERTE( pT->m_pComponentData->m_pNode != NULL );
  865. return pT->m_pComponentData->m_pNode->GetResultViewType(ppViewType, pViewOptions);
  866. #else // FIX_PROBLEM_WITH_GET_RESULT_VIEW_TYPE_NULL_COOKIE
  867. *ppViewType = NULL;
  868. *pViewOptions = MMC_VIEW_OPTIONS_NONE;
  869. return S_FALSE;
  870. #endif //FIX_PROBLEM_WITH_GET_RESULT_VIEW_TYPE_NULL_COOKIE
  871. }
  872. CSnapInItem* pItem = (CSnapInItem*)cookie;
  873. return pItem->GetResultViewType(ppViewType, pViewOptions);
  874. }
  875. STDMETHOD(GetDisplayInfo)(RESULTDATAITEM *pResultDataItem)
  876. {
  877. ATLTRACE(_T("IComponentImpl::GetDisplayInfo\n"));
  878. ATLASSERT(pResultDataItem != NULL);
  879. if (pResultDataItem == NULL)
  880. {
  881. ATLTRACE(_T("IComponent::GetDisplayInfo called with pResultDataItem==NULL\n"));
  882. return E_POINTER;
  883. }
  884. CSnapInItem* pItem = (CSnapInItem*) pResultDataItem->lParam;
  885. if (pItem == NULL)
  886. {
  887. ATLTRACE(_T("Invalid Item\n"));
  888. return E_UNEXPECTED;
  889. }
  890. return pItem->GetResultPaneInfo(pResultDataItem);
  891. }
  892. STDMETHOD(CompareObjects)( LPDATAOBJECT lpDataObjectA,
  893. LPDATAOBJECT lpDataObjectB)
  894. {
  895. ATLTRACENOTIMPL(_T("IComponentImpl::CompareObjects\n"));
  896. }
  897. CComPtr<IConsole> m_spConsole;
  898. };
  899. template <class T>
  900. HRESULT IComponentImpl<T>::Notify(LPDATAOBJECT lpDataObject,
  901. MMC_NOTIFY_TYPE event,
  902. LPARAM arg,
  903. LPARAM param)
  904. {
  905. ATLTRACE(_T("IComponentImpl::Notify\n"));
  906. HRESULT hr = E_POINTER;
  907. ATLASSERT(lpDataObject != NULL);
  908. if (lpDataObject == NULL)
  909. ATLTRACE(_T("IComponent::Notify called with lpDataObject==NULL \n"));
  910. else
  911. {
  912. T* pT = static_cast<T*>(this);
  913. CSnapInItem* pItem;
  914. DATA_OBJECT_TYPES type;
  915. // Make sure that the object is derived from CSnapInObjectRoot
  916. hr = pT->m_pComponentData->GetDataClass(lpDataObject, &pItem, &type);
  917. if (SUCCEEDED(hr))
  918. hr = pItem->Notify(event, arg, param, NULL, pT, type);
  919. }
  920. return hr;
  921. }
  922. template <class T, class D>
  923. class ATL_NO_VTABLE IResultDataCompareImpl : public IResultDataCompare
  924. {
  925. public:
  926. STDMETHOD(Compare)(LPARAM lUserParam,
  927. MMC_COOKIE cookieA,
  928. MMC_COOKIE cookieB,
  929. int *pnResult)
  930. {
  931. ATLTRACENOTIMPL(_T("IResultDataCompareImpl::Compare"));
  932. }
  933. };
  934. template <class T>
  935. class ATL_NO_VTABLE IExtendContextMenuImpl : public IExtendContextMenu
  936. {
  937. public:
  938. STDMETHOD(AddMenuItems)(LPDATAOBJECT pDataObject,
  939. LPCONTEXTMENUCALLBACK piCallback,
  940. long *pInsertionAllowed);
  941. STDMETHOD(Command)(long lCommandID,
  942. LPDATAOBJECT pDataObject);
  943. };
  944. template <class T>
  945. inline HRESULT IExtendContextMenuImpl<T>::AddMenuItems(LPDATAOBJECT pDataObject,
  946. LPCONTEXTMENUCALLBACK piCallback,
  947. long *pInsertionAllowed)
  948. {
  949. ATLTRACE(_T("IExtendContextMenuImpl::AddMenuItems\n"));
  950. HRESULT hr = E_POINTER;
  951. ATLASSERT(pDataObject != NULL);
  952. if (pDataObject == NULL)
  953. ATLTRACE(_T("IExtendContextMenu::AddMenuItems called with pDataObject==NULL\n"));
  954. else
  955. {
  956. T* pT = static_cast<T*>(this);
  957. CSnapInItem* pItem;
  958. DATA_OBJECT_TYPES type;
  959. hr = pT->m_pComponentData->GetDataClass(pDataObject, &pItem, &type);
  960. if (SUCCEEDED(hr))
  961. hr = pItem->AddMenuItems(piCallback, pInsertionAllowed, type);
  962. }
  963. return hr;
  964. }
  965. template <class T>
  966. inline HRESULT IExtendContextMenuImpl<T>::Command(long lCommandID,
  967. LPDATAOBJECT pDataObject)
  968. {
  969. ATLTRACE(_T("IExtendContextMenuImpl::Command\n"));
  970. HRESULT hr = E_POINTER;
  971. ATLASSERT(pDataObject != NULL);
  972. if (pDataObject == NULL)
  973. ATLTRACE(_T("IExtendContextMenu::Command called with pDataObject==NULL\n"));
  974. else
  975. {
  976. T* pT = static_cast<T*>(this);
  977. CSnapInItem* pItem;
  978. DATA_OBJECT_TYPES type;
  979. hr = pT->m_pComponentData->GetDataClass(pDataObject, &pItem, &type);
  980. if (SUCCEEDED(hr))
  981. hr = pItem->Command(lCommandID, (CSnapInObjectRootBase*)pT, type);
  982. }
  983. return hr;
  984. }
  985. template<class T>
  986. class ATL_NO_VTABLE IExtendPropertySheetImpl : public IExtendPropertySheet2
  987. {
  988. public:
  989. STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider,
  990. LONG_PTR handle,
  991. LPDATAOBJECT pDataObject);
  992. STDMETHOD(QueryPagesFor)(LPDATAOBJECT pDataObject);
  993. STDMETHOD(GetWatermarks)(
  994. LPDATAOBJECT lpIDataObject,
  995. HBITMAP *lphWatermark,
  996. HBITMAP *lphHeader,
  997. HPALETTE *lphPalette,
  998. BOOL *bStretch);
  999. };
  1000. template<class T>
  1001. inline HRESULT IExtendPropertySheetImpl<T>::GetWatermarks(
  1002. LPDATAOBJECT lpIDataObject,
  1003. HBITMAP *lphWatermark,
  1004. HBITMAP *lphHeader,
  1005. HPALETTE *lphPalette,
  1006. BOOL *bStretch)
  1007. {
  1008. ATLTRACE(_T("IExtendPropertySheetImpl::GetWatermarks\n"));
  1009. return E_NOTIMPL;
  1010. }
  1011. template<class T>
  1012. inline HRESULT IExtendPropertySheetImpl<T>::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  1013. LONG_PTR handle,
  1014. LPDATAOBJECT pDataObject)
  1015. {
  1016. ATLTRACE(_T("IExtendPropertySheetImpl::CreatePropertyPages\n"));
  1017. HRESULT hr = E_POINTER;
  1018. ATLASSERT(pDataObject != NULL);
  1019. if (pDataObject == NULL)
  1020. ATLTRACE(_T("IExtendPropertySheetImpl::CreatePropertyPages called with pDataObject==NULL\n"));
  1021. else
  1022. {
  1023. T* pT = static_cast<T*>(this);
  1024. CSnapInItem* pItem;
  1025. DATA_OBJECT_TYPES type;
  1026. hr = pT->m_pComponentData->GetDataClass(pDataObject, &pItem, &type);
  1027. if (SUCCEEDED(hr))
  1028. hr = pItem->CreatePropertyPages(lpProvider, handle, this, type);
  1029. }
  1030. return hr;
  1031. }
  1032. template <class T>
  1033. inline HRESULT IExtendPropertySheetImpl<T>::QueryPagesFor(LPDATAOBJECT pDataObject)
  1034. {
  1035. ATLTRACE(_T("IExtendPropertySheetImpl::QueryPagesFor\n"));
  1036. HRESULT hr = E_POINTER;
  1037. ATLASSERT(pDataObject != NULL);
  1038. if (pDataObject == NULL)
  1039. ATLTRACE(_T("IExtendPropertySheetImpl::QueryPagesFor called with pDataObject==NULL\n"));
  1040. else
  1041. {
  1042. T* pT = static_cast<T*>(this);
  1043. CSnapInItem* pItem;
  1044. DATA_OBJECT_TYPES type;
  1045. hr = pT->m_pComponentData->GetDataClass(pDataObject, &pItem, &type);
  1046. if (SUCCEEDED(hr))
  1047. hr = pItem->QueryPagesFor(type);
  1048. }
  1049. return hr;
  1050. }
  1051. template <class T>
  1052. class ATL_NO_VTABLE IExtendControlbarImpl : public IExtendControlbar
  1053. {
  1054. public:
  1055. STDMETHOD(SetControlbar)(LPCONTROLBAR pControlbar)
  1056. {
  1057. ATLTRACE(_T("IExtendControlbarImpl::SetControlbar\n"));
  1058. T* pT = static_cast<T*>(this);
  1059. if (pT->m_spControlbar != NULL)
  1060. {
  1061. int n = pT->m_toolbarMap.GetSize();
  1062. for (int i = 0; i < n; i++)
  1063. {
  1064. IToolbar* pToolbar = (IToolbar*)pT->m_toolbarMap.GetValueAt(i);
  1065. if (pToolbar != NULL)
  1066. {
  1067. pT->m_spControlbar->Detach(pToolbar);
  1068. pToolbar->Release();
  1069. }
  1070. }
  1071. }
  1072. pT->m_toolbarMap.RemoveAll();
  1073. pT->m_spControlbar = pControlbar;
  1074. return S_OK;
  1075. }
  1076. STDMETHOD(ControlbarNotify)(MMC_NOTIFY_TYPE event,
  1077. LPARAM arg,
  1078. LPARAM param);
  1079. };
  1080. template <class T>
  1081. inline HRESULT IExtendControlbarImpl<T>::ControlbarNotify(MMC_NOTIFY_TYPE event,
  1082. LPARAM arg,
  1083. LPARAM param)
  1084. {
  1085. ATLTRACE(_T("IExtendControlbarImpl::ControlbarNotify\n"));
  1086. CSnapInItem* pItem = NULL;
  1087. DATA_OBJECT_TYPES type;
  1088. HRESULT hr = S_OK;
  1089. T* pT = static_cast<T*>(this);
  1090. if (event == MMCN_BTN_CLICK)
  1091. hr = pT->m_pComponentData->GetDataClass((IDataObject*) arg, &pItem, &type);
  1092. else if (event == MMCN_SELECT)
  1093. {
  1094. hr = pT->m_pComponentData->GetDataClass((IDataObject*) param, &pItem, &type);
  1095. BOOL bSelect = (BOOL) HIWORD (arg);
  1096. BOOL bScope = (BOOL) LOWORD(arg);
  1097. if (bSelect)
  1098. {
  1099. int n = pT->m_toolbarMap.GetSize();
  1100. for (int i = 0; i < n; i++)
  1101. {
  1102. IToolbar* pToolbar = (IToolbar*)pT->m_toolbarMap.GetValueAt(i);
  1103. if (pToolbar != NULL)
  1104. pT->m_spControlbar->Detach(pToolbar);
  1105. }
  1106. }
  1107. }
  1108. if (SUCCEEDED(hr))
  1109. hr = pItem->ControlbarNotify(pT->m_spControlbar, this, &(pT->m_toolbarMap), event, arg, param, (CSnapInObjectRootBase*) pT, type);
  1110. return hr;
  1111. }
  1112. #ifdef TASKPAD_SUPPORT
  1113. template <class T>
  1114. class ATL_NO_VTABLE IExtendTaskPadImpl : public IExtendTaskPad
  1115. {
  1116. public:
  1117. STDMETHOD(TaskNotify)(
  1118. /* [in] */ IDataObject __RPC_FAR *lpDataObject,
  1119. /* [in] */ VARIANT __RPC_FAR *pvarg,
  1120. /* [in] */ VARIANT __RPC_FAR *pvparam)
  1121. {
  1122. ATLTRACE(_T("IExtendTaskPadImpl::TaskNotify\n"));
  1123. HRESULT hr = E_POINTER;
  1124. ATLASSERT(lpDataObject != NULL);
  1125. if (lpDataObject == NULL)
  1126. ATLTRACE(_T("IExtendTaskPadImpl::TaskNotify called with lpDataObject==NULL \n"));
  1127. else
  1128. {
  1129. T* pT = static_cast<T*>(this);
  1130. CSnapInItem* pItem;
  1131. DATA_OBJECT_TYPES type;
  1132. ATLASSERT(pT->m_pComponentData != NULL);
  1133. hr = pT->m_pComponentData->GetDataClass(lpDataObject, &pItem, &type);
  1134. if (SUCCEEDED(hr))
  1135. hr = pItem->TaskNotify(
  1136. lpDataObject
  1137. , pvarg
  1138. , pvparam
  1139. );
  1140. }
  1141. return hr;
  1142. }
  1143. STDMETHOD(EnumTasks)(
  1144. /* [in] */ IDataObject __RPC_FAR *lpDataObject,
  1145. /* [in] */ LPOLESTR szTaskGroup,
  1146. /* [out] */ IEnumTASK __RPC_FAR *__RPC_FAR *ppEnumTASK)
  1147. {
  1148. ATLTRACE(_T("IExtendTaskPadImpl::EnumTasks\n"));
  1149. HRESULT hr = E_POINTER;
  1150. ATLASSERT(lpDataObject != NULL);
  1151. if (lpDataObject == NULL)
  1152. ATLTRACE(_T("IExtendTaskPadImpl::EnumTasks called with lpDataObject==NULL \n"));
  1153. else
  1154. {
  1155. T* pT = static_cast<T*>(this);
  1156. CSnapInItem* pItem;
  1157. DATA_OBJECT_TYPES type;
  1158. ATLASSERT(pT->m_pComponentData != NULL);
  1159. hr = pT->m_pComponentData->GetDataClass(lpDataObject, &pItem, &type);
  1160. if (SUCCEEDED(hr))
  1161. hr = pItem->EnumTasks(
  1162. lpDataObject
  1163. , szTaskGroup
  1164. , ppEnumTASK
  1165. );
  1166. }
  1167. return hr;
  1168. }
  1169. STDMETHOD(GetTitle)(
  1170. /* [in,string] */ LPOLESTR szGroup,
  1171. /* [out,string] */ LPOLESTR *pszTitle)
  1172. {
  1173. ATLTRACENOTIMPL(_T("IExtendTaskPadImpl::GetTitle\n"));
  1174. }
  1175. STDMETHOD(GetDescriptiveText)(
  1176. /* [in,string] */ LPOLESTR pszGroup,
  1177. /* [out,string] */ LPOLESTR *pszDescriptiveText)
  1178. {
  1179. ATLTRACENOTIMPL(_T("IExtendTaskPadImpl::GetDescriptiveText\n"));
  1180. }
  1181. STDMETHOD(GetBackground)(
  1182. /* [in,string] */ LPOLESTR pszGroup,
  1183. /* [out] */ MMC_TASK_DISPLAY_OBJECT *pTDO )
  1184. {
  1185. ATLTRACENOTIMPL(_T("IExtendTaskPadImpl::GetBackground\n"));
  1186. }
  1187. STDMETHOD(GetListPadInfo)(
  1188. /* [string][in] */ LPOLESTR pszGroup,
  1189. /* [out] */ MMC_LISTPAD_INFO __RPC_FAR *lpListPadInfo)
  1190. {
  1191. ATLTRACENOTIMPL(_T("IExtendTaskPadImpl::GetListPadInfo\n"));
  1192. }
  1193. };
  1194. #endif // TASKPAD_SUPPORT
  1195. #define SNAPINMENUID(id) \
  1196. public: \
  1197. static const UINT GetMenuID() \
  1198. { \
  1199. static const UINT IDMENU = id; \
  1200. return id; \
  1201. }
  1202. #define EXT_SNAPINMENUID(id) \
  1203. public: \
  1204. static const UINT GetMenuID() \
  1205. { \
  1206. static const UINT IDMENU = id; \
  1207. return id; \
  1208. }
  1209. #define BEGIN_SNAPINCOMMAND_MAP(theClass, bIsExtension) \
  1210. HRESULT ProcessCommand(UINT nID, \
  1211. bool& bHandled, \
  1212. CSnapInObjectRootBase* pObj, \
  1213. DATA_OBJECT_TYPES type) \
  1214. { \
  1215. bHandled = true; \
  1216. HRESULT hr = S_OK;
  1217. #define SNAPINCOMMAND_ENTRY(id, func) \
  1218. if (id == nID) \
  1219. { \
  1220. hr = func(bHandled, pObj); \
  1221. if (bHandled) \
  1222. return hr; \
  1223. }
  1224. #define SNAPINCOMMAND_RANGE_ENTRY(id1, id2, func) \
  1225. if (id1 >= nID && nID <= id2) \
  1226. { \
  1227. hr = func(nID, bHandled, pObj); \
  1228. if (bHandled) \
  1229. return hr; \
  1230. }
  1231. #define CHAIN_SNAPINCOMMAND_MAP(theChainClass) \
  1232. { \
  1233. hr = theChainClass::ProcessCommand(nID, bHandled, pObj, type); \
  1234. if (bHandled) \
  1235. return hr; \
  1236. }
  1237. #define END_SNAPINCOMMAND_MAP() \
  1238. return hr; \
  1239. }
  1240. struct CSnapInToolBarData
  1241. {
  1242. WORD wVersion;
  1243. WORD wWidth;
  1244. WORD wHeight;
  1245. WORD wItemCount;
  1246. //WORD aItems[wItemCount]
  1247. WORD* items()
  1248. { return (WORD*)(this+1); }
  1249. };
  1250. #define RT_TOOLBAR MAKEINTRESOURCE(241)
  1251. class CSnapInToolbarInfo
  1252. {
  1253. public:
  1254. ~CSnapInToolbarInfo()
  1255. {
  1256. CleanUp();
  1257. }
  1258. HRESULT CleanUp()
  1259. {
  1260. if (m_pStrToolTip)
  1261. {
  1262. for (UINT i = 0; i < m_nButtonCount; i++)
  1263. {
  1264. delete m_pStrToolTip[i];
  1265. m_pStrToolTip[i] = NULL;
  1266. }
  1267. delete [] m_pStrToolTip;
  1268. m_pStrToolTip = NULL;
  1269. }
  1270. if (m_pStrButtonText)
  1271. {
  1272. for (UINT i = 0; i < m_nButtonCount; i++)
  1273. {
  1274. delete m_pStrButtonText[i];
  1275. m_pStrButtonText[i] = NULL;
  1276. }
  1277. delete [] m_pStrButtonText;
  1278. m_pStrButtonText = NULL;
  1279. }
  1280. if (m_pnButtonID)
  1281. {
  1282. delete m_pnButtonID;
  1283. m_pnButtonID = NULL;
  1284. }
  1285. m_nButtonCount = 0;
  1286. return S_OK;
  1287. }
  1288. OLECHAR** m_pStrToolTip;
  1289. OLECHAR** m_pStrButtonText;
  1290. UINT* m_pnButtonID;
  1291. UINT m_idToolbar;
  1292. UINT m_nButtonCount;
  1293. };
  1294. #define BEGIN_SNAPINTOOLBARID_MAP(theClass) \
  1295. public: \
  1296. static CSnapInToolbarInfo* GetToolbarInfo() \
  1297. { \
  1298. static CSnapInToolbarInfo m_toolbarInfo[] = \
  1299. {
  1300. #define SNAPINTOOLBARID_ENTRY(id) \
  1301. { NULL, NULL, NULL, id, 0},
  1302. #define END_SNAPINTOOLBARID_MAP() \
  1303. { NULL, NULL, NULL, 0, 0} \
  1304. }; \
  1305. return m_toolbarInfo; \
  1306. }
  1307. class GdiObjectSentry
  1308. {
  1309. public:
  1310. GdiObjectSentry(HGDIOBJ object) throw ()
  1311. : obj(object)
  1312. {
  1313. }
  1314. ~GdiObjectSentry() throw ()
  1315. {
  1316. DeleteObject(obj);
  1317. }
  1318. private:
  1319. HGDIOBJ obj;
  1320. // Not implemented.
  1321. GdiObjectSentry(const GdiObjectSentry&);
  1322. GdiObjectSentry& operator=(const GdiObjectSentry&);
  1323. };
  1324. template <class T, BOOL bIsExtension = FALSE>
  1325. class ATL_NO_VTABLE CSnapInItemImpl : public CSnapInItem
  1326. {
  1327. public:
  1328. CSnapInItemImpl(unsigned int helpIndex = 0)
  1329. :CSnapInItem(helpIndex)
  1330. {
  1331. }
  1332. virtual ~CSnapInItemImpl()
  1333. {
  1334. }
  1335. public:
  1336. STDMETHOD(Notify)( MMC_NOTIFY_TYPE event,
  1337. LPARAM arg,
  1338. LPARAM param,
  1339. IComponentData* pComponentData,
  1340. IComponent* pComponent,
  1341. DATA_OBJECT_TYPES type)
  1342. {
  1343. ATLASSERT("Override Function in Derived Class");
  1344. ATLTRACENOTIMPL(_T("CSnapInItemImpl::Notify"));
  1345. }
  1346. STDMETHOD(GetScopePaneInfo)(SCOPEDATAITEM *pScopeDataItem)
  1347. {
  1348. ATLTRACENOTIMPL(_T("CSnapInItemImpl::GetScopePaneInfo"));
  1349. }
  1350. STDMETHOD(GetResultViewType)(LPOLESTR *ppViewType,
  1351. long *pViewOptions)
  1352. {
  1353. ATLTRACE(_T("CSnapInItemImpl::GetResultViewType\n"));
  1354. *ppViewType = NULL;
  1355. *pViewOptions = MMC_VIEW_OPTIONS_NONE;
  1356. return S_FALSE;
  1357. }
  1358. STDMETHOD(GetResultPaneInfo)(RESULTDATAITEM *pResultDataItem)
  1359. {
  1360. ATLTRACENOTIMPL(_T("CSnapInItemImpl::GetResultPaneInfo"));
  1361. }
  1362. STDMETHOD(AddMenuItems)(LPCONTEXTMENUCALLBACK piCallback,
  1363. long *pInsertionAllowed,
  1364. DATA_OBJECT_TYPES type)
  1365. {
  1366. ATLTRACE(_T("CSnapInItemImpl::AddMenuItems\n"));
  1367. T* pT = static_cast<T*>(this);
  1368. if (!bIsExtension)
  1369. pT->SetMenuInsertionFlags(true, pInsertionAllowed);
  1370. UINT menuID = pT->GetMenuID();
  1371. if (menuID == 0)
  1372. return S_OK;
  1373. HMENU hMenu = LoadMenu(_Module.GetResourceInstance(), MAKEINTRESOURCE(menuID));
  1374. long insertionID;
  1375. if (hMenu)
  1376. {
  1377. for (int i = 0; 1; i++)
  1378. {
  1379. HMENU hSubMenu = GetSubMenu(hMenu, i);
  1380. if (hSubMenu == NULL)
  1381. break;
  1382. MENUITEMINFO menuItemInfo;
  1383. memset(&menuItemInfo, 0, sizeof(menuItemInfo));
  1384. menuItemInfo.cbSize = sizeof(menuItemInfo);
  1385. switch (i)
  1386. {
  1387. case 0:
  1388. if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP) )
  1389. continue;
  1390. insertionID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  1391. break;
  1392. case 1:
  1393. if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) )
  1394. continue;
  1395. if (bIsExtension)
  1396. insertionID = CCM_INSERTIONPOINTID_3RDPARTY_NEW;
  1397. else
  1398. insertionID = CCM_INSERTIONPOINTID_PRIMARY_NEW;
  1399. break;
  1400. case 2:;
  1401. if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK) )
  1402. continue;
  1403. if (bIsExtension)
  1404. insertionID = CCM_INSERTIONPOINTID_3RDPARTY_TASK;
  1405. else
  1406. insertionID = CCM_INSERTIONPOINTID_PRIMARY_TASK;
  1407. break;
  1408. case 3:;
  1409. if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW) )
  1410. continue;
  1411. insertionID = CCM_INSERTIONPOINTID_PRIMARY_VIEW;
  1412. break;
  1413. default:
  1414. {
  1415. insertionID = 0;
  1416. continue;
  1417. }
  1418. break;
  1419. }
  1420. menuItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
  1421. menuItemInfo.fType = MFT_STRING;
  1422. TCHAR szMenuText[128];
  1423. for (int j = 0; 1; j++)
  1424. {
  1425. menuItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
  1426. menuItemInfo.fType = MFT_STRING;
  1427. menuItemInfo.cch = 128;
  1428. menuItemInfo.dwTypeData = szMenuText;
  1429. TCHAR szStatusBar[256];
  1430. if (!GetMenuItemInfo(hSubMenu, j, TRUE, &menuItemInfo))
  1431. break;
  1432. if (menuItemInfo.fType != MFT_STRING)
  1433. continue;
  1434. pT->UpdateMenuState(menuItemInfo.wID, szMenuText, &menuItemInfo.fState);
  1435. LoadString(_Module.GetResourceInstance(), menuItemInfo.wID, szStatusBar, 256);
  1436. OLECHAR wszStatusBar[256];
  1437. OLECHAR wszMenuText[128];
  1438. USES_CONVERSION;
  1439. ocscpy(wszMenuText, T2OLE(szMenuText));
  1440. ocscpy(wszStatusBar, T2OLE(szStatusBar));
  1441. CONTEXTMENUITEM contextMenuItem;
  1442. contextMenuItem.strName = wszMenuText;
  1443. contextMenuItem.strStatusBarText = wszStatusBar;
  1444. contextMenuItem.lCommandID = menuItemInfo.wID;
  1445. contextMenuItem.lInsertionPointID = insertionID;
  1446. contextMenuItem.fFlags = menuItemInfo.fState;
  1447. contextMenuItem.fSpecialFlags = 0;
  1448. HRESULT hr = piCallback->AddItem(&contextMenuItem);
  1449. ATLASSERT(SUCCEEDED(hr));
  1450. }
  1451. }
  1452. DestroyMenu(hMenu);
  1453. }
  1454. if (!bIsExtension)
  1455. pT->SetMenuInsertionFlags(true, pInsertionAllowed);
  1456. return S_OK;
  1457. }
  1458. STDMETHOD(Command)(long lCommandID,
  1459. CSnapInObjectRootBase* pObj,
  1460. DATA_OBJECT_TYPES type)
  1461. {
  1462. ATLTRACE(_T("CSnapInItemImpl::Command\n"));
  1463. bool bHandled;
  1464. T* pT = static_cast<T*>(this);
  1465. return pT->ProcessCommand(lCommandID, bHandled, pObj, type);
  1466. }
  1467. STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider,
  1468. LONG_PTR handle,
  1469. IUnknown* pUnk,
  1470. DATA_OBJECT_TYPES type)
  1471. {
  1472. ATLASSERT("Override Function in Derived Class");
  1473. ATLTRACENOTIMPL(_T("CSnapInItemImpl::CreatePropertyPages"));
  1474. }
  1475. STDMETHOD(QueryPagesFor)(DATA_OBJECT_TYPES type)
  1476. {
  1477. ATLASSERT("Override Function in Derived Class");
  1478. ATLTRACENOTIMPL(_T("CSnapInItemImpl::QueryPagesFor"));
  1479. }
  1480. STDMETHOD(SetControlbar)(IControlbar *pControlbar,
  1481. IExtendControlbar* pExtendControlBar,
  1482. CSimpleMap<UINT, IUnknown*>* pToolbarMap)
  1483. {
  1484. ATLTRACE(_T("CSnapInItemImpl::SetControlbar\n"));
  1485. T* pT = static_cast<T*>(this);
  1486. CSnapInToolbarInfo* pInfo = pT->GetToolbarInfo();
  1487. if (pInfo == NULL)
  1488. return S_OK;
  1489. for( ; pInfo->m_idToolbar; pInfo++)
  1490. {
  1491. IToolbar* p = (IToolbar*) pToolbarMap->Lookup(pInfo->m_idToolbar);
  1492. if (p != NULL)
  1493. continue;
  1494. HBITMAP hBitmap = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(pInfo->m_idToolbar));
  1495. if (hBitmap == NULL)
  1496. return S_OK;
  1497. GdiObjectSentry sentry(hBitmap);
  1498. HRSRC hRsrc = ::FindResource(_Module.GetResourceInstance(), MAKEINTRESOURCE(pInfo->m_idToolbar), RT_TOOLBAR);
  1499. if (hRsrc == NULL)
  1500. return S_OK;
  1501. HGLOBAL hGlobal = LoadResource(_Module.GetResourceInstance(), hRsrc);
  1502. if (hGlobal == NULL)
  1503. return S_OK;
  1504. CSnapInToolBarData* pData = (CSnapInToolBarData*)LockResource(hGlobal);
  1505. if (pData == NULL)
  1506. return S_OK;
  1507. ATLASSERT(pData->wVersion == 1);
  1508. ATLASSERT(pData->wWidth == 16);
  1509. ATLASSERT(pData->wHeight == 16);
  1510. pInfo->m_nButtonCount = pData->wItemCount;
  1511. if (pInfo->m_pnButtonID == NULL)
  1512. pInfo->m_pnButtonID = new UINT[pInfo->m_nButtonCount];
  1513. if (pInfo->m_pnButtonID == NULL)
  1514. continue;
  1515. MMCBUTTON *pButtons = new MMCBUTTON[pData->wItemCount];
  1516. if (pButtons == NULL)
  1517. {
  1518. delete []pInfo->m_pnButtonID;
  1519. continue;
  1520. }
  1521. if (pInfo->m_pStrToolTip == NULL)
  1522. {
  1523. pInfo->m_pStrToolTip = new OLECHAR* [pData->wItemCount];
  1524. if (pInfo->m_pStrToolTip)
  1525. memset(pInfo->m_pStrToolTip, 0, sizeof(OLECHAR*) * pData->wItemCount);
  1526. }
  1527. if (pInfo->m_pStrToolTip == NULL)
  1528. {
  1529. delete []pInfo->m_pnButtonID;
  1530. delete []pButtons;
  1531. continue;
  1532. }
  1533. for (int i = 0, j = 0; i < pData->wItemCount; i++)
  1534. {
  1535. pInfo->m_pnButtonID[i] = pButtons[i].idCommand = pData->items()[i];
  1536. if (pButtons[i].idCommand)
  1537. {
  1538. pButtons[i].nBitmap = j++;
  1539. // get the statusbar string and allow modification of the button state
  1540. TCHAR szStatusBar[512];
  1541. LoadString(_Module.GetResourceInstance(), pButtons[i].idCommand, szStatusBar, 512);
  1542. if (pInfo->m_pStrToolTip[i] == NULL)
  1543. pInfo->m_pStrToolTip[i] = new OLECHAR[lstrlen(szStatusBar) + 1];
  1544. if (pInfo->m_pStrToolTip[i] == NULL)
  1545. continue;
  1546. USES_CONVERSION;
  1547. ocscpy(pInfo->m_pStrToolTip[i], T2OLE(szStatusBar));
  1548. pButtons[i].lpTooltipText = pInfo->m_pStrToolTip[i];
  1549. pButtons[i].lpButtonText = OLESTR("");
  1550. pButtons[i].fsState = TBSTATE_ENABLED;
  1551. pButtons[i].fsType = TBSTYLE_BUTTON;
  1552. pT->SetToolbarButtonInfo(pButtons[i].idCommand, &pButtons[i].fsState, &pButtons[i].fsType);
  1553. }
  1554. else
  1555. {
  1556. pButtons[i].lpTooltipText = OLESTR("");
  1557. pButtons[i].lpButtonText = OLESTR("");
  1558. pButtons[i].fsType = TBSTYLE_SEP;
  1559. pButtons[i].fsState = 0;
  1560. }
  1561. }
  1562. IToolbar* pToolbar;
  1563. HRESULT hr = pControlbar->Create(TOOLBAR, pExtendControlBar, reinterpret_cast<LPUNKNOWN*>(&pToolbar));
  1564. if (SUCCEEDED(hr))
  1565. {
  1566. hr = pToolbar->AddBitmap(pData->wItemCount, hBitmap, pData->wWidth, pData->wHeight, RGB(255, 0, 255));
  1567. if (SUCCEEDED(hr))
  1568. {
  1569. hr = pToolbar->AddButtons(pData->wItemCount, pButtons);
  1570. if (SUCCEEDED(hr))
  1571. {
  1572. pToolbar->AddRef();
  1573. pToolbarMap->Add(pInfo->m_idToolbar, (IUnknown*)pToolbar);
  1574. }
  1575. }
  1576. }
  1577. pToolbar->Release();
  1578. delete [] pButtons;
  1579. }
  1580. return S_OK;
  1581. }
  1582. STDMETHOD(ControlbarNotify)(IControlbar *pControlbar,
  1583. IExtendControlbar *pExtendControlbar,
  1584. CSimpleMap<UINT, IUnknown*>* pToolbarMap,
  1585. MMC_NOTIFY_TYPE event,
  1586. LPARAM arg,
  1587. LPARAM param,
  1588. CSnapInObjectRootBase* pObj,
  1589. DATA_OBJECT_TYPES type)
  1590. {
  1591. ATLTRACE(_T("CSnapInItemImpl::ControlbarNotify\n"));
  1592. T* pT = static_cast<T*>(this);
  1593. SetControlbar(pControlbar, pExtendControlbar, pToolbarMap);
  1594. if(event == MMCN_SELECT)
  1595. {
  1596. if (pControlbar == NULL)
  1597. return S_OK;
  1598. BOOL bSelect = (BOOL) HIWORD (arg);
  1599. BOOL bScope = (BOOL) LOWORD(arg);
  1600. CSnapInToolbarInfo* pInfo = pT->GetToolbarInfo();
  1601. if (pInfo == NULL)
  1602. return S_OK;
  1603. for(; pInfo->m_idToolbar; pInfo++)
  1604. {
  1605. IToolbar* pToolbar = (IToolbar*)pToolbarMap->Lookup(pInfo->m_idToolbar);
  1606. if (pToolbar == NULL)
  1607. continue;
  1608. if (!bSelect && bScope)
  1609. pControlbar->Detach(pToolbar);
  1610. else
  1611. {
  1612. pControlbar->Attach(TOOLBAR, pToolbar);
  1613. for (UINT i = 0; i < pInfo->m_nButtonCount; i++)
  1614. {
  1615. if (pInfo->m_pnButtonID[i])
  1616. {
  1617. pToolbar->SetButtonState(pInfo->m_pnButtonID[i],
  1618. ENABLED,
  1619. pT->UpdateToolbarButton(pInfo->m_pnButtonID[i],
  1620. ENABLED));
  1621. pToolbar->SetButtonState(pInfo->m_pnButtonID[i],
  1622. CHECKED,
  1623. pT->UpdateToolbarButton(pInfo->m_pnButtonID[i],
  1624. CHECKED));
  1625. pToolbar->SetButtonState(pInfo->m_pnButtonID[i],
  1626. HIDDEN,
  1627. pT->UpdateToolbarButton(pInfo->m_pnButtonID[i],
  1628. HIDDEN));
  1629. pToolbar->SetButtonState(pInfo->m_pnButtonID[i],
  1630. INDETERMINATE,
  1631. pT->UpdateToolbarButton(pInfo->m_pnButtonID[i],
  1632. INDETERMINATE));
  1633. pToolbar->SetButtonState(pInfo->m_pnButtonID[i],
  1634. BUTTONPRESSED,
  1635. pT->UpdateToolbarButton(pInfo->m_pnButtonID[i],
  1636. BUTTONPRESSED));
  1637. }
  1638. }
  1639. }
  1640. }
  1641. return S_OK;
  1642. }
  1643. else if (event == MMCN_BTN_CLICK)
  1644. {
  1645. bool bHandled;
  1646. return pT->ProcessCommand((UINT) param, bHandled, pObj, type);
  1647. }
  1648. return E_UNEXPECTED;
  1649. }
  1650. STDMETHOD(GetScopeData)(SCOPEDATAITEM **pScopeDataItem)
  1651. {
  1652. if (pScopeDataItem == NULL)
  1653. return E_FAIL;
  1654. *pScopeDataItem = &m_scopeDataItem;
  1655. return S_OK;
  1656. }
  1657. STDMETHOD(GetResultData)(RESULTDATAITEM **pResultDataItem)
  1658. {
  1659. if (pResultDataItem == NULL)
  1660. return E_FAIL;
  1661. *pResultDataItem = &m_resultDataItem;
  1662. return S_OK;
  1663. }
  1664. STDMETHOD(GetDataObject)(IDataObject** pDataObj, DATA_OBJECT_TYPES type)
  1665. {
  1666. CComObject<CSnapInDataObjectImpl>* pData;
  1667. HRESULT hr = CComObject<CSnapInDataObjectImpl>::CreateInstance(&pData);
  1668. if (FAILED(hr))
  1669. return hr;
  1670. T* pT = static_cast<T*> (this);
  1671. pData->m_objectData.m_pItem = pT;
  1672. pData->m_objectData.m_type = type;
  1673. hr = pData->QueryInterface(IID_IDataObject, (void**)(pDataObj));
  1674. return hr;
  1675. }
  1676. void UpdateMenuState(UINT id, LPTSTR pBuf, UINT *flags)
  1677. {
  1678. return;
  1679. }
  1680. void SetToolbarButtonInfo(UINT id, BYTE *pfsState, BYTE *pfsType)
  1681. {
  1682. *pfsState = TBSTATE_ENABLED;
  1683. *pfsType = TBSTYLE_BUTTON;
  1684. }
  1685. BOOL UpdateToolbarButton(UINT id, BYTE fsState)
  1686. {
  1687. if (fsState == ENABLED)
  1688. return TRUE;
  1689. return FALSE;
  1690. }
  1691. HRESULT ProcessCommand(UINT nID,
  1692. bool& bHandled,
  1693. CSnapInObjectRootBase* pObj,
  1694. DATA_OBJECT_TYPES type)
  1695. {
  1696. ATLTRACE(_T("No handler for item with ID %d\n"), nID);
  1697. return S_OK;
  1698. }
  1699. STDMETHOD (FillData)(CLIPFORMAT cf, LPSTREAM pStream)
  1700. {
  1701. HRESULT hr = DV_E_CLIPFORMAT;
  1702. ULONG uWritten;
  1703. T* pT = static_cast<T*> (this);
  1704. if (cf == m_CCF_NODETYPE)
  1705. {
  1706. hr = pStream->Write(pT->GetNodeType(), sizeof(GUID), &uWritten);
  1707. return hr;
  1708. }
  1709. if (cf == m_CCF_SZNODETYPE)
  1710. {
  1711. hr = pStream->Write(pT->GetSZNodeType(), (ocslen((OLECHAR*)pT->GetSZNodeType()) + 1 )* sizeof(OLECHAR), &uWritten);
  1712. return hr;
  1713. }
  1714. if (cf == m_CCF_DISPLAY_NAME)
  1715. {
  1716. hr = pStream->Write(pT->GetDisplayName(), (ocslen((OLECHAR*)pT->GetDisplayName()) + 1) * sizeof(OLECHAR), &uWritten);
  1717. return hr;
  1718. }
  1719. if (cf == m_CCF_SNAPIN_CLASSID)
  1720. {
  1721. hr = pStream->Write(pT->GetSnapInCLSID(), sizeof(GUID), &uWritten);
  1722. return hr;
  1723. }
  1724. return hr;
  1725. }
  1726. static CSnapInToolbarInfo* GetToolbarInfo()
  1727. {
  1728. return NULL;
  1729. }
  1730. static const UINT GetMenuID()
  1731. {
  1732. return 0;
  1733. }
  1734. void SetMenuInsertionFlags(bool bBeforeInsertion, long* pInsertionAllowed)
  1735. {
  1736. }
  1737. void* GetNodeType()
  1738. {
  1739. return (void*)T::m_NODETYPE;
  1740. }
  1741. void* GetSZNodeType()
  1742. {
  1743. return (void*)T::m_SZNODETYPE;
  1744. }
  1745. void* GetDisplayName()
  1746. {
  1747. return (void*)T::m_SZDISPLAY_NAME;
  1748. }
  1749. void* GetSnapInCLSID()
  1750. {
  1751. return (void*)T::m_SNAPIN_CLASSID;
  1752. }
  1753. CComBSTR m_bstrDisplayName;
  1754. SCOPEDATAITEM m_scopeDataItem;
  1755. RESULTDATAITEM m_resultDataItem;
  1756. #ifdef TASKPAD_SUPPORT
  1757. STDMETHOD(TaskNotify)(
  1758. IDataObject * pDataObject
  1759. , VARIANT * pvarg
  1760. , VARIANT * pvparam
  1761. )
  1762. {
  1763. ATLTRACENOTIMPL(_T("CSnapInItemImpl::TaskNotify"));
  1764. }
  1765. STDMETHOD(EnumTasks)(
  1766. IDataObject * pDataObject
  1767. , BSTR szTaskGroup
  1768. , IEnumTASK** ppEnumTASK
  1769. )
  1770. {
  1771. ATLTRACENOTIMPL(_T("CSnapInItemImpl::EnumTasks"));
  1772. }
  1773. #endif // TASKPAD_SUPPORT
  1774. };
  1775. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_NODETYPE = 0;
  1776. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_SZNODETYPE = 0;
  1777. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_DISPLAY_NAME = 0;
  1778. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_SNAPIN_CLASSID = 0;
  1779. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_SNAPIN_GETOBJECTDATA = 0;
  1780. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_MMC_MULTISELECT_DATAOBJECT = 0;
  1781. #endif //__ATL_SNAPIN_H__