Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2074 lines
56 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 = (DLGPROC)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. *ppItem = NULL;
  439. *pType = CCT_UNINITIALIZED;
  440. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  441. FORMATETC formatetc = { m_CCF_SNAPIN_GETOBJECTDATA,
  442. NULL,
  443. DVASPECT_CONTENT,
  444. -1,
  445. TYMED_HGLOBAL
  446. };
  447. stgmedium.hGlobal = GlobalAlloc(0, sizeof(CObjectData));
  448. if (stgmedium.hGlobal == NULL)
  449. return E_OUTOFMEMORY;
  450. HRESULT hr = pDataObj->GetDataHere(&formatetc, &stgmedium);
  451. if (SUCCEEDED(hr))
  452. {
  453. CObjectData* pData = (CObjectData*)stgmedium.hGlobal;
  454. *ppItem = pData->m_pItem;
  455. *pType = pData->m_type;
  456. }
  457. GlobalFree(stgmedium.hGlobal);
  458. return hr;
  459. }
  460. #ifdef TASKPAD_SUPPORT
  461. STDMETHOD(TaskNotify)(
  462. IDataObject * pDataObject
  463. , VARIANT * pvarg
  464. , VARIANT * pvparam
  465. ) = 0;
  466. STDMETHOD(EnumTasks)(
  467. IDataObject * pDataObject
  468. , BSTR szTaskGroup
  469. , IEnumTASK** ppEnumTASK
  470. ) = 0;
  471. #endif // TASKPAD_SUPPORT
  472. virtual HRESULT STDMETHODCALLTYPE GetDataObject(IDataObject** pDataObj, DATA_OBJECT_TYPES type) = 0;
  473. static void Init()
  474. {
  475. m_CCF_NODETYPE = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_NODETYPE"));
  476. m_CCF_SZNODETYPE = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_SZNODETYPE"));
  477. m_CCF_DISPLAY_NAME = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_DISPLAY_NAME"));
  478. m_CCF_SNAPIN_CLASSID = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_SNAPIN_CLASSID"));
  479. m_CCF_SNAPIN_GETOBJECTDATA = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_GETOBJECTDATA"));
  480. m_CCF_MMC_MULTISELECT_DATAOBJECT = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_MMC_MULTISELECT_DATAOBJECT"));
  481. }
  482. public:
  483. static CLIPFORMAT m_CCF_NODETYPE;
  484. static CLIPFORMAT m_CCF_SZNODETYPE;
  485. static CLIPFORMAT m_CCF_DISPLAY_NAME;
  486. static CLIPFORMAT m_CCF_SNAPIN_CLASSID;
  487. static CLIPFORMAT m_CCF_SNAPIN_GETOBJECTDATA;
  488. static CLIPFORMAT m_CCF_MMC_MULTISELECT_DATAOBJECT;
  489. // IAS: Added to store some information about which help file to use
  490. unsigned int m_helpIndex;
  491. };
  492. class CSnapInObjectRootBase
  493. {
  494. public:
  495. CComPtr <IControlbar> m_spControlbar;
  496. CSimpleMap <UINT, IUnknown*> m_toolbarMap;
  497. const int m_ntype;
  498. CSnapInObjectRootBase(int n = 0) : m_ntype(n)
  499. {
  500. }
  501. HRESULT GetDataClass(IDataObject* pDataObject, CSnapInItem** ppItem, DATA_OBJECT_TYPES* pType)
  502. {
  503. return CSnapInItem::GetDataClass(pDataObject, ppItem, pType);
  504. }
  505. #ifdef FIX_PROBLEM_WITH_DYNAMIC_CAST_ON_CSNAPINOBJECTROOT_NOT_WORKING
  506. // Need at least one virtual method, or compiler does not generate a vtable
  507. virtual ~CSnapInObjectRootBase()
  508. {
  509. }
  510. #endif FIX_PROBLEM_WITH_DYNAMIC_CAST_ON_CSNAPINOBJECTROOT_NOT_WORKING
  511. };
  512. template <int n, class ComponentData>
  513. class CSnapInObjectRoot : public CSnapInObjectRootBase
  514. {
  515. public :
  516. CSnapInObjectRoot() : CSnapInObjectRootBase(n)
  517. {
  518. m_pComponentData = NULL;
  519. }
  520. ComponentData* m_pComponentData;
  521. };
  522. #define EXTENSION_SNAPIN_DATACLASS(dataClass) dataClass m_##dataClass;
  523. #define BEGIN_EXTENSION_SNAPIN_NODEINFO_MAP(classname) \
  524. HRESULT GetDataClass(IDataObject* pDataObject, CSnapInItem** ppItem, DATA_OBJECT_TYPES* pType) \
  525. { \
  526. if (ppItem == NULL) \
  527. return E_POINTER; \
  528. if (pType == NULL) \
  529. return E_POINTER; \
  530. \
  531. *ppItem = NULL; \
  532. \
  533. *pType = CCT_UNINITIALIZED; \
  534. \
  535. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL }; \
  536. FORMATETC formatetc = { CSnapInItem::m_CCF_NODETYPE, \
  537. NULL, \
  538. DVASPECT_CONTENT, \
  539. -1, \
  540. TYMED_HGLOBAL \
  541. }; \
  542. \
  543. stgmedium.hGlobal = GlobalAlloc(0, sizeof(GUID)); \
  544. if (stgmedium.hGlobal == NULL) \
  545. return E_OUTOFMEMORY; \
  546. \
  547. HRESULT hr = pDataObject->GetDataHere(&formatetc, &stgmedium); \
  548. if (FAILED(hr)) \
  549. { \
  550. GlobalFree(stgmedium.hGlobal); \
  551. return hr; \
  552. } \
  553. \
  554. GUID guid; \
  555. memcpy(&guid, stgmedium.hGlobal, sizeof(GUID)); \
  556. \
  557. GlobalFree(stgmedium.hGlobal); \
  558. hr = S_OK;
  559. #define EXTENSION_SNAPIN_NODEINFO_ENTRY(dataClass) \
  560. if (IsEqualGUID(guid, *(GUID*)m_##dataClass.GetNodeType())) \
  561. { \
  562. *ppItem = m_##dataClass.GetExtNodeObject(pDataObject, &m_##dataClass); \
  563. _ASSERTE(*ppItem != NULL); \
  564. (*ppItem)->InitDataClass(pDataObject, &m_##dataClass); \
  565. return hr; \
  566. }
  567. #define END_EXTENSION_SNAPIN_NODEINFO_MAP() \
  568. return CSnapInItem::GetDataClass(pDataObject, ppItem, pType); \
  569. };
  570. class ATL_NO_VTABLE CSnapInDataObjectImpl : public IDataObject,
  571. public CComObjectRoot
  572. {
  573. public:
  574. BEGIN_COM_MAP(CSnapInDataObjectImpl)
  575. COM_INTERFACE_ENTRY(IDataObject)
  576. END_COM_MAP()
  577. STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
  578. {
  579. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::GetData\n"));
  580. }
  581. STDMETHOD(GetDataHere)(FORMATETC* pformatetc, STGMEDIUM* pmedium)
  582. {
  583. ATLTRACE(_T("SnapInDataObjectImpl::GetDataHere\n"));
  584. if (pmedium == NULL)
  585. return E_POINTER;
  586. HRESULT hr = DV_E_TYMED;
  587. // Make sure the type medium is HGLOBAL
  588. if (pmedium->tymed == TYMED_HGLOBAL)
  589. {
  590. // Create the stream on the hGlobal passed in
  591. CComPtr<IStream> spStream;
  592. hr = CreateStreamOnHGlobal(pmedium->hGlobal, FALSE, &spStream);
  593. if (SUCCEEDED(hr))
  594. if (pformatetc->cfFormat == CSnapInItem::m_CCF_SNAPIN_GETOBJECTDATA)
  595. {
  596. hr = DV_E_CLIPFORMAT;
  597. ULONG uWritten;
  598. hr = spStream->Write(&m_objectData, sizeof(CObjectData), &uWritten);
  599. }
  600. else
  601. hr = m_objectData.m_pItem->FillData(pformatetc->cfFormat, spStream);
  602. }
  603. return hr;
  604. }
  605. STDMETHOD(QueryGetData)(FORMATETC* /* pformatetc */)
  606. {
  607. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::QueryGetData\n"));
  608. }
  609. STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */)
  610. {
  611. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::GetCanonicalFormatEtc\n"));
  612. }
  613. STDMETHOD(SetData)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */)
  614. {
  615. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetData\n"));
  616. }
  617. STDMETHOD(EnumFormatEtc)(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */)
  618. {
  619. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::EnumFormatEtc\n"));
  620. }
  621. STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink,
  622. DWORD *pdwConnection)
  623. {
  624. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetData\n"));
  625. }
  626. STDMETHOD(DUnadvise)(DWORD dwConnection)
  627. {
  628. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetDatan\n"));
  629. }
  630. STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise)
  631. {
  632. ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetData\n"));
  633. }
  634. CObjectData m_objectData;
  635. };
  636. template <class T, class Component>
  637. class ATL_NO_VTABLE IComponentDataImpl : public IComponentData
  638. {
  639. public :
  640. IComponentDataImpl()
  641. {
  642. m_pNode = NULL;
  643. }
  644. STDMETHOD(Initialize)(LPUNKNOWN pUnknown)
  645. {
  646. ATLTRACE(_T("IComponentDataImpl::Initialize\n"));
  647. HRESULT hr = E_POINTER;
  648. ATLASSERT(pUnknown != NULL);
  649. if (pUnknown == NULL)
  650. ATLTRACE(_T("IComponentData::Initialize called with pUnknown == NULL\n"));
  651. else
  652. {
  653. hr = pUnknown->QueryInterface(IID_IConsole, (void**)&m_spConsole);
  654. if (FAILED(hr))
  655. ATLTRACE(_T("QI for IConsole failed\n"));
  656. }
  657. return hr;
  658. }
  659. STDMETHOD(CreateComponent)(LPCOMPONENT *ppComponent)
  660. {
  661. ATLTRACE(_T("IComponentDataImpl::CreateComponent\n"));
  662. HRESULT hr = E_POINTER;
  663. ATLASSERT(ppComponent != NULL);
  664. if (ppComponent == NULL)
  665. ATLTRACE(_T("IComponentData::CreateComponent called with ppComponent == NULL\n"));
  666. else
  667. {
  668. *ppComponent = NULL;
  669. CComObject< Component >* pComponent;
  670. hr = CComObject< Component >::CreateInstance(&pComponent);
  671. ATLASSERT(SUCCEEDED(hr));
  672. if (FAILED(hr))
  673. ATLTRACE(_T("IComponentData::CreateComponent : Could not create IComponent object\n"));
  674. else
  675. {
  676. pComponent->m_pComponentData = static_cast<T*>(this);
  677. hr = pComponent->QueryInterface(IID_IComponent, (void**)ppComponent);
  678. }
  679. }
  680. return hr;
  681. }
  682. STDMETHOD(Notify)(
  683. LPDATAOBJECT lpDataObject,
  684. MMC_NOTIFY_TYPE event,
  685. LPARAM arg,
  686. LPARAM param)
  687. {
  688. ATLTRACE(_T("IComponentDataImpl::Notify\n"));
  689. HRESULT hr = E_POINTER;
  690. ATLASSERT(lpDataObject != NULL);
  691. if (lpDataObject == NULL)
  692. ATLTRACE(_T("IComponentData::Notify called with lpDataObject == NULL\n"));
  693. else
  694. {
  695. T* pT = static_cast<T*>(this);
  696. CSnapInItem* pItem;
  697. DATA_OBJECT_TYPES type;
  698. hr = pT->m_pComponentData->GetDataClass(lpDataObject, &pItem, &type);
  699. ATLASSERT(SUCCEEDED(hr));
  700. if (SUCCEEDED(hr))
  701. hr = pItem->Notify(event, arg, param, pT, NULL, type);
  702. }
  703. return hr;
  704. }
  705. STDMETHOD(Destroy)(void)
  706. {
  707. ATLTRACE(_T("IComponentDataImpl::Destroy\n"));
  708. T* pT = static_cast<T*>(this);
  709. if (pT->m_spControlbar != NULL)
  710. {
  711. int n = pT->m_toolbarMap.GetSize();
  712. for (int i = 0; i < n; i++)
  713. {
  714. IToolbar* pToolbar = (IToolbar*)pT->m_toolbarMap.GetValueAt(i);
  715. if (pToolbar != NULL)
  716. {
  717. pT->m_spControlbar->Detach(pToolbar);
  718. pToolbar->Release();
  719. }
  720. }
  721. }
  722. pT->m_toolbarMap.RemoveAll();
  723. m_spConsole.Release();
  724. return S_OK;
  725. }
  726. STDMETHOD(QueryDataObject)(MMC_COOKIE cookie,
  727. DATA_OBJECT_TYPES type,
  728. LPDATAOBJECT *ppDataObject)
  729. {
  730. ATLTRACE(_T("IComponentDataImpl::QueryDataObject\n"));
  731. HRESULT hr = E_POINTER;
  732. ATLASSERT(ppDataObject != NULL);
  733. if (ppDataObject == NULL)
  734. ATLTRACE(_T("IComponentData::QueryDataObject called with ppDataObject == NULL\n"));
  735. else
  736. {
  737. *ppDataObject = NULL;
  738. CSnapInItem* pItem = (CSnapInItem*) cookie;
  739. if (cookie == NULL)
  740. pItem = m_pNode;
  741. hr = pItem->GetDataObject(ppDataObject, type);
  742. }
  743. return hr;
  744. }
  745. STDMETHOD(GetDisplayInfo)(SCOPEDATAITEM *pScopeDataItem)
  746. {
  747. ATLTRACE(_T("IComponentDataImpl::GetDisplayInfo\n"));
  748. HRESULT hr = E_POINTER;
  749. ATLASSERT(pScopeDataItem != NULL);
  750. if (pScopeDataItem == NULL)
  751. ATLTRACE(_T("IComponentData::GetDisplayInfo called with pScopeDataItem == NULL\n"));
  752. else
  753. {
  754. CSnapInItem* pItem= (CSnapInItem*) pScopeDataItem->lParam;
  755. if (pItem == NULL)
  756. pItem = m_pNode;
  757. hr = E_UNEXPECTED;
  758. if (pItem != NULL)
  759. hr = pItem->GetScopePaneInfo(pScopeDataItem);
  760. }
  761. return hr;
  762. }
  763. STDMETHOD(CompareObjects)(LPDATAOBJECT lpDataObjectA,
  764. LPDATAOBJECT lpDataObjectB)
  765. {
  766. ATLTRACENOTIMPL(_T("IComponentDataImpl::CompareObjects\n"));
  767. }
  768. CComPtr<IConsole> m_spConsole;
  769. CSnapInItem* m_pNode;
  770. };
  771. template <class T>
  772. class ATL_NO_VTABLE IComponentImpl : public IComponent
  773. {
  774. public:
  775. STDMETHOD(Initialize)(LPCONSOLE lpConsole)
  776. {
  777. ATLTRACE(_T("IComponentImpl::Initialize\n"));
  778. HRESULT hr = E_POINTER;
  779. ATLASSERT(lpConsole != NULL);
  780. if (lpConsole == NULL)
  781. ATLTRACE(_T("lpConsole is NULL\n"));
  782. else
  783. {
  784. m_spConsole = lpConsole;
  785. CComPtr<IHeaderCtrl> spHeaderCtrl;
  786. hr = m_spConsole->QueryInterface(IID_IHeaderCtrl, (void**)&spHeaderCtrl);
  787. if (FAILED(hr))
  788. ATLTRACE(_T("QI for IHeaderCtrl failed\n"));
  789. else
  790. {
  791. hr = m_spConsole->SetHeader(spHeaderCtrl);
  792. if (FAILED(hr))
  793. ATLTRACE(_T("IConsole::SetHeader failed (HRESULT = %x)\n"), hr);
  794. }
  795. }
  796. return hr;
  797. }
  798. STDMETHOD(Notify)(LPDATAOBJECT lpDataObject,
  799. MMC_NOTIFY_TYPE event,
  800. LPARAM arg,
  801. LPARAM param);
  802. STDMETHOD(Destroy)(MMC_COOKIE cookie)
  803. {
  804. ATLTRACE(_T("IComponentImpl::Destroy\n"));
  805. T* pT = static_cast<T*>(this);
  806. if (pT->m_spControlbar != NULL)
  807. {
  808. int n = pT->m_toolbarMap.GetSize();
  809. for (int i = 0; i < n; i++)
  810. {
  811. IToolbar* pToolbar = (IToolbar*)pT->m_toolbarMap.GetValueAt(i);
  812. if (pToolbar != NULL)
  813. {
  814. pT->m_spControlbar->Detach(pToolbar);
  815. pToolbar->Release();
  816. }
  817. }
  818. }
  819. pT->m_toolbarMap.RemoveAll();
  820. m_spConsole->SetHeader(NULL);
  821. m_spConsole.Release();
  822. return S_OK;
  823. }
  824. STDMETHOD(QueryDataObject)(MMC_COOKIE cookie,
  825. DATA_OBJECT_TYPES type,
  826. LPDATAOBJECT *ppDataObject)
  827. {
  828. ATLTRACE(_T("IComponentImpl::QueryDataObject\n"));
  829. ATLASSERT(ppDataObject != NULL);
  830. if (ppDataObject == NULL)
  831. {
  832. ATLTRACE(_T("IComponent::QueryDataObject called with ppDataObject==NULL \n"));
  833. return E_POINTER;
  834. }
  835. if (cookie == NULL)
  836. {
  837. ATLTRACE(_T("IComponent::QueryDataObject called with cookie==NULL \n"));
  838. return E_UNEXPECTED;
  839. }
  840. *ppDataObject = NULL;
  841. if (cookie == MMC_MULTI_SELECT_COOKIE)
  842. {
  843. ATLTRACE(_T("Override QueryDataObject to handle multiselect\n"));
  844. return E_UNEXPECTED;
  845. }
  846. CSnapInItem* pItem = (CSnapInItem*) cookie;
  847. return pItem->GetDataObject(ppDataObject, type);
  848. }
  849. STDMETHOD(GetResultViewType)(MMC_COOKIE cookie,
  850. LPOLESTR *ppViewType,
  851. long *pViewOptions)
  852. {
  853. ATLTRACE(_T("IComponentImpl::GetResultViewType\n"));
  854. if (cookie == NULL)
  855. {
  856. #ifdef FIX_PROBLEM_WITH_GET_RESULT_VIEW_TYPE_NULL_COOKIE
  857. T* pT = static_cast<T*>(this);
  858. // We are being asked about our root node.
  859. _ASSERTE( pT->m_pComponentData!= NULL );
  860. _ASSERTE( pT->m_pComponentData->m_pNode != NULL );
  861. return pT->m_pComponentData->m_pNode->GetResultViewType(ppViewType, pViewOptions);
  862. #else // FIX_PROBLEM_WITH_GET_RESULT_VIEW_TYPE_NULL_COOKIE
  863. *ppViewType = NULL;
  864. *pViewOptions = MMC_VIEW_OPTIONS_NONE;
  865. return S_FALSE;
  866. #endif //FIX_PROBLEM_WITH_GET_RESULT_VIEW_TYPE_NULL_COOKIE
  867. }
  868. CSnapInItem* pItem = (CSnapInItem*)cookie;
  869. return pItem->GetResultViewType(ppViewType, pViewOptions);
  870. }
  871. STDMETHOD(GetDisplayInfo)(RESULTDATAITEM *pResultDataItem)
  872. {
  873. ATLTRACE(_T("IComponentImpl::GetDisplayInfo\n"));
  874. ATLASSERT(pResultDataItem != NULL);
  875. if (pResultDataItem == NULL)
  876. {
  877. ATLTRACE(_T("IComponent::GetDisplayInfo called with pResultDataItem==NULL\n"));
  878. return E_POINTER;
  879. }
  880. CSnapInItem* pItem = (CSnapInItem*) pResultDataItem->lParam;
  881. if (pItem == NULL)
  882. {
  883. ATLTRACE(_T("Invalid Item\n"));
  884. return E_UNEXPECTED;
  885. }
  886. return pItem->GetResultPaneInfo(pResultDataItem);
  887. }
  888. STDMETHOD(CompareObjects)( LPDATAOBJECT lpDataObjectA,
  889. LPDATAOBJECT lpDataObjectB)
  890. {
  891. ATLTRACENOTIMPL(_T("IComponentImpl::CompareObjects\n"));
  892. }
  893. CComPtr<IConsole> m_spConsole;
  894. };
  895. template <class T>
  896. HRESULT IComponentImpl<T>::Notify(LPDATAOBJECT lpDataObject,
  897. MMC_NOTIFY_TYPE event,
  898. LPARAM arg,
  899. LPARAM param)
  900. {
  901. ATLTRACE(_T("IComponentImpl::Notify\n"));
  902. HRESULT hr = E_POINTER;
  903. ATLASSERT(lpDataObject != NULL);
  904. if (lpDataObject == NULL)
  905. ATLTRACE(_T("IComponent::Notify called with lpDataObject==NULL \n"));
  906. else
  907. {
  908. T* pT = static_cast<T*>(this);
  909. CSnapInItem* pItem;
  910. DATA_OBJECT_TYPES type;
  911. // Make sure that the object is derived from CSnapInObjectRoot
  912. hr = pT->m_pComponentData->GetDataClass(lpDataObject, &pItem, &type);
  913. if (SUCCEEDED(hr))
  914. hr = pItem->Notify(event, arg, param, NULL, pT, type);
  915. }
  916. return hr;
  917. }
  918. template <class T, class D>
  919. class ATL_NO_VTABLE IResultDataCompareImpl : public IResultDataCompare
  920. {
  921. public:
  922. STDMETHOD(Compare)(LPARAM lUserParam,
  923. MMC_COOKIE cookieA,
  924. MMC_COOKIE cookieB,
  925. int *pnResult)
  926. {
  927. ATLTRACENOTIMPL(_T("IResultDataCompareImpl::Compare"));
  928. }
  929. };
  930. template <class T>
  931. class ATL_NO_VTABLE IExtendContextMenuImpl : public IExtendContextMenu
  932. {
  933. public:
  934. STDMETHOD(AddMenuItems)(LPDATAOBJECT pDataObject,
  935. LPCONTEXTMENUCALLBACK piCallback,
  936. long *pInsertionAllowed);
  937. STDMETHOD(Command)(long lCommandID,
  938. LPDATAOBJECT pDataObject);
  939. };
  940. template <class T>
  941. inline HRESULT IExtendContextMenuImpl<T>::AddMenuItems(LPDATAOBJECT pDataObject,
  942. LPCONTEXTMENUCALLBACK piCallback,
  943. long *pInsertionAllowed)
  944. {
  945. ATLTRACE(_T("IExtendContextMenuImpl::AddMenuItems\n"));
  946. HRESULT hr = E_POINTER;
  947. ATLASSERT(pDataObject != NULL);
  948. if (pDataObject == NULL)
  949. ATLTRACE(_T("IExtendContextMenu::AddMenuItems called with pDataObject==NULL\n"));
  950. else
  951. {
  952. T* pT = static_cast<T*>(this);
  953. CSnapInItem* pItem;
  954. DATA_OBJECT_TYPES type;
  955. hr = pT->m_pComponentData->GetDataClass(pDataObject, &pItem, &type);
  956. if (SUCCEEDED(hr))
  957. hr = pItem->AddMenuItems(piCallback, pInsertionAllowed, type);
  958. }
  959. return hr;
  960. }
  961. template <class T>
  962. inline HRESULT IExtendContextMenuImpl<T>::Command(long lCommandID,
  963. LPDATAOBJECT pDataObject)
  964. {
  965. ATLTRACE(_T("IExtendContextMenuImpl::Command\n"));
  966. HRESULT hr = E_POINTER;
  967. ATLASSERT(pDataObject != NULL);
  968. if (pDataObject == NULL)
  969. ATLTRACE(_T("IExtendContextMenu::Command called with pDataObject==NULL\n"));
  970. else
  971. {
  972. T* pT = static_cast<T*>(this);
  973. CSnapInItem* pItem;
  974. DATA_OBJECT_TYPES type;
  975. hr = pT->m_pComponentData->GetDataClass(pDataObject, &pItem, &type);
  976. if (SUCCEEDED(hr))
  977. hr = pItem->Command(lCommandID, (CSnapInObjectRootBase*)pT, type);
  978. }
  979. return hr;
  980. }
  981. template<class T>
  982. class ATL_NO_VTABLE IExtendPropertySheetImpl : public IExtendPropertySheet2
  983. {
  984. public:
  985. STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider,
  986. LONG_PTR handle,
  987. LPDATAOBJECT pDataObject);
  988. STDMETHOD(QueryPagesFor)(LPDATAOBJECT pDataObject);
  989. STDMETHOD(GetWatermarks)(
  990. LPDATAOBJECT lpIDataObject,
  991. HBITMAP *lphWatermark,
  992. HBITMAP *lphHeader,
  993. HPALETTE *lphPalette,
  994. BOOL *bStretch);
  995. };
  996. template<class T>
  997. inline HRESULT IExtendPropertySheetImpl<T>::GetWatermarks(
  998. LPDATAOBJECT lpIDataObject,
  999. HBITMAP *lphWatermark,
  1000. HBITMAP *lphHeader,
  1001. HPALETTE *lphPalette,
  1002. BOOL *bStretch)
  1003. {
  1004. ATLTRACE(_T("IExtendPropertySheetImpl::GetWatermarks\n"));
  1005. return E_NOTIMPL;
  1006. }
  1007. template<class T>
  1008. inline HRESULT IExtendPropertySheetImpl<T>::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  1009. LONG_PTR handle,
  1010. LPDATAOBJECT pDataObject)
  1011. {
  1012. ATLTRACE(_T("IExtendPropertySheetImpl::CreatePropertyPages\n"));
  1013. HRESULT hr = E_POINTER;
  1014. ATLASSERT(pDataObject != NULL);
  1015. if (pDataObject == NULL)
  1016. ATLTRACE(_T("IExtendPropertySheetImpl::CreatePropertyPages called with pDataObject==NULL\n"));
  1017. else
  1018. {
  1019. T* pT = static_cast<T*>(this);
  1020. CSnapInItem* pItem;
  1021. DATA_OBJECT_TYPES type;
  1022. hr = pT->m_pComponentData->GetDataClass(pDataObject, &pItem, &type);
  1023. if (SUCCEEDED(hr))
  1024. hr = pItem->CreatePropertyPages(lpProvider, handle, this, type);
  1025. }
  1026. return hr;
  1027. }
  1028. template <class T>
  1029. inline HRESULT IExtendPropertySheetImpl<T>::QueryPagesFor(LPDATAOBJECT pDataObject)
  1030. {
  1031. ATLTRACE(_T("IExtendPropertySheetImpl::QueryPagesFor\n"));
  1032. HRESULT hr = E_POINTER;
  1033. ATLASSERT(pDataObject != NULL);
  1034. if (pDataObject == NULL)
  1035. ATLTRACE(_T("IExtendPropertySheetImpl::QueryPagesFor called with pDataObject==NULL\n"));
  1036. else
  1037. {
  1038. T* pT = static_cast<T*>(this);
  1039. CSnapInItem* pItem;
  1040. DATA_OBJECT_TYPES type;
  1041. hr = pT->m_pComponentData->GetDataClass(pDataObject, &pItem, &type);
  1042. if (SUCCEEDED(hr))
  1043. hr = pItem->QueryPagesFor(type);
  1044. }
  1045. return hr;
  1046. }
  1047. template <class T>
  1048. class ATL_NO_VTABLE IExtendControlbarImpl : public IExtendControlbar
  1049. {
  1050. public:
  1051. STDMETHOD(SetControlbar)(LPCONTROLBAR pControlbar)
  1052. {
  1053. ATLTRACE(_T("IExtendControlbarImpl::SetControlbar\n"));
  1054. T* pT = static_cast<T*>(this);
  1055. if (pT->m_spControlbar != NULL)
  1056. {
  1057. int n = pT->m_toolbarMap.GetSize();
  1058. for (int i = 0; i < n; i++)
  1059. {
  1060. IToolbar* pToolbar = (IToolbar*)pT->m_toolbarMap.GetValueAt(i);
  1061. if (pToolbar != NULL)
  1062. {
  1063. pT->m_spControlbar->Detach(pToolbar);
  1064. pToolbar->Release();
  1065. }
  1066. }
  1067. }
  1068. pT->m_toolbarMap.RemoveAll();
  1069. pT->m_spControlbar = pControlbar;
  1070. return S_OK;
  1071. }
  1072. STDMETHOD(ControlbarNotify)(MMC_NOTIFY_TYPE event,
  1073. LPARAM arg,
  1074. LPARAM param);
  1075. };
  1076. template <class T>
  1077. inline HRESULT IExtendControlbarImpl<T>::ControlbarNotify(MMC_NOTIFY_TYPE event,
  1078. LPARAM arg,
  1079. LPARAM param)
  1080. {
  1081. ATLTRACE(_T("IExtendControlbarImpl::ControlbarNotify\n"));
  1082. CSnapInItem* pItem = NULL;
  1083. DATA_OBJECT_TYPES type;
  1084. HRESULT hr = S_OK;
  1085. T* pT = static_cast<T*>(this);
  1086. if (event == MMCN_BTN_CLICK)
  1087. hr = pT->m_pComponentData->GetDataClass((IDataObject*) arg, &pItem, &type);
  1088. else if (event == MMCN_SELECT)
  1089. {
  1090. hr = pT->m_pComponentData->GetDataClass((IDataObject*) param, &pItem, &type);
  1091. BOOL bSelect = (BOOL) HIWORD (arg);
  1092. BOOL bScope = (BOOL) LOWORD(arg);
  1093. if (bSelect)
  1094. {
  1095. int n = pT->m_toolbarMap.GetSize();
  1096. for (int i = 0; i < n; i++)
  1097. {
  1098. IToolbar* pToolbar = (IToolbar*)pT->m_toolbarMap.GetValueAt(i);
  1099. if (pToolbar != NULL)
  1100. pT->m_spControlbar->Detach(pToolbar);
  1101. }
  1102. }
  1103. }
  1104. if (SUCCEEDED(hr))
  1105. hr = pItem->ControlbarNotify(pT->m_spControlbar, this, &(pT->m_toolbarMap), event, arg, param, (CSnapInObjectRootBase*) pT, type);
  1106. return hr;
  1107. }
  1108. #ifdef TASKPAD_SUPPORT
  1109. template <class T>
  1110. class ATL_NO_VTABLE IExtendTaskPadImpl : public IExtendTaskPad
  1111. {
  1112. public:
  1113. STDMETHOD(TaskNotify)(
  1114. /* [in] */ IDataObject __RPC_FAR *lpDataObject,
  1115. /* [in] */ VARIANT __RPC_FAR *pvarg,
  1116. /* [in] */ VARIANT __RPC_FAR *pvparam)
  1117. {
  1118. ATLTRACE(_T("IExtendTaskPadImpl::TaskNotify\n"));
  1119. HRESULT hr = E_POINTER;
  1120. ATLASSERT(lpDataObject != NULL);
  1121. if (lpDataObject == NULL)
  1122. ATLTRACE(_T("IExtendTaskPadImpl::TaskNotify called with lpDataObject==NULL \n"));
  1123. else
  1124. {
  1125. T* pT = static_cast<T*>(this);
  1126. CSnapInItem* pItem;
  1127. DATA_OBJECT_TYPES type;
  1128. ATLASSERT(pT->m_pComponentData != NULL);
  1129. hr = pT->m_pComponentData->GetDataClass(lpDataObject, &pItem, &type);
  1130. if (SUCCEEDED(hr))
  1131. hr = pItem->TaskNotify(
  1132. lpDataObject
  1133. , pvarg
  1134. , pvparam
  1135. );
  1136. }
  1137. return hr;
  1138. }
  1139. STDMETHOD(EnumTasks)(
  1140. /* [in] */ IDataObject __RPC_FAR *lpDataObject,
  1141. /* [in] */ LPOLESTR szTaskGroup,
  1142. /* [out] */ IEnumTASK __RPC_FAR *__RPC_FAR *ppEnumTASK)
  1143. {
  1144. ATLTRACE(_T("IExtendTaskPadImpl::EnumTasks\n"));
  1145. HRESULT hr = E_POINTER;
  1146. ATLASSERT(lpDataObject != NULL);
  1147. if (lpDataObject == NULL)
  1148. ATLTRACE(_T("IExtendTaskPadImpl::EnumTasks called with lpDataObject==NULL \n"));
  1149. else
  1150. {
  1151. T* pT = static_cast<T*>(this);
  1152. CSnapInItem* pItem;
  1153. DATA_OBJECT_TYPES type;
  1154. ATLASSERT(pT->m_pComponentData != NULL);
  1155. hr = pT->m_pComponentData->GetDataClass(lpDataObject, &pItem, &type);
  1156. if (SUCCEEDED(hr))
  1157. hr = pItem->EnumTasks(
  1158. lpDataObject
  1159. , szTaskGroup
  1160. , ppEnumTASK
  1161. );
  1162. }
  1163. return hr;
  1164. }
  1165. STDMETHOD(GetTitle)(
  1166. /* [in,string] */ LPOLESTR szGroup,
  1167. /* [out,string] */ LPOLESTR *pszTitle)
  1168. {
  1169. ATLTRACENOTIMPL(_T("IExtendTaskPadImpl::GetTitle\n"));
  1170. }
  1171. STDMETHOD(GetDescriptiveText)(
  1172. /* [in,string] */ LPOLESTR pszGroup,
  1173. /* [out,string] */ LPOLESTR *pszDescriptiveText)
  1174. {
  1175. ATLTRACENOTIMPL(_T("IExtendTaskPadImpl::GetDescriptiveText\n"));
  1176. }
  1177. STDMETHOD(GetBackground)(
  1178. /* [in,string] */ LPOLESTR pszGroup,
  1179. /* [out] */ MMC_TASK_DISPLAY_OBJECT *pTDO )
  1180. {
  1181. ATLTRACENOTIMPL(_T("IExtendTaskPadImpl::GetBackground\n"));
  1182. }
  1183. STDMETHOD(GetListPadInfo)(
  1184. /* [string][in] */ LPOLESTR pszGroup,
  1185. /* [out] */ MMC_LISTPAD_INFO __RPC_FAR *lpListPadInfo)
  1186. {
  1187. ATLTRACENOTIMPL(_T("IExtendTaskPadImpl::GetListPadInfo\n"));
  1188. }
  1189. };
  1190. #endif // TASKPAD_SUPPORT
  1191. #define SNAPINMENUID(id) \
  1192. public: \
  1193. static const UINT GetMenuID() \
  1194. { \
  1195. static const UINT IDMENU = id; \
  1196. return id; \
  1197. }
  1198. #define EXT_SNAPINMENUID(id) \
  1199. public: \
  1200. static const UINT GetMenuID() \
  1201. { \
  1202. static const UINT IDMENU = id; \
  1203. return id; \
  1204. }
  1205. #define BEGIN_SNAPINCOMMAND_MAP(theClass, bIsExtension) \
  1206. HRESULT ProcessCommand(UINT nID, \
  1207. bool& bHandled, \
  1208. CSnapInObjectRootBase* pObj, \
  1209. DATA_OBJECT_TYPES type) \
  1210. { \
  1211. bHandled = true; \
  1212. HRESULT hr = S_OK;
  1213. #define SNAPINCOMMAND_ENTRY(id, func) \
  1214. if (id == nID) \
  1215. { \
  1216. hr = func(bHandled, pObj); \
  1217. if (bHandled) \
  1218. return hr; \
  1219. }
  1220. #define SNAPINCOMMAND_RANGE_ENTRY(id1, id2, func) \
  1221. if (id1 >= nID && nID <= id2) \
  1222. { \
  1223. hr = func(nID, bHandled, pObj); \
  1224. if (bHandled) \
  1225. return hr; \
  1226. }
  1227. #define CHAIN_SNAPINCOMMAND_MAP(theChainClass) \
  1228. { \
  1229. hr = theChainClass::ProcessCommand(nID, bHandled, pObj, type); \
  1230. if (bHandled) \
  1231. return hr; \
  1232. }
  1233. #define END_SNAPINCOMMAND_MAP() \
  1234. return hr; \
  1235. }
  1236. struct CSnapInToolBarData
  1237. {
  1238. WORD wVersion;
  1239. WORD wWidth;
  1240. WORD wHeight;
  1241. WORD wItemCount;
  1242. //WORD aItems[wItemCount]
  1243. WORD* items()
  1244. { return (WORD*)(this+1); }
  1245. };
  1246. #define RT_TOOLBAR MAKEINTRESOURCE(241)
  1247. class CSnapInToolbarInfo
  1248. {
  1249. public:
  1250. ~CSnapInToolbarInfo()
  1251. {
  1252. CleanUp();
  1253. }
  1254. HRESULT CleanUp()
  1255. {
  1256. if (m_pStrToolTip)
  1257. {
  1258. for (UINT i = 0; i < m_nButtonCount; i++)
  1259. {
  1260. delete m_pStrToolTip[i];
  1261. m_pStrToolTip[i] = NULL;
  1262. }
  1263. delete [] m_pStrToolTip;
  1264. m_pStrToolTip = NULL;
  1265. }
  1266. if (m_pStrButtonText)
  1267. {
  1268. for (UINT i = 0; i < m_nButtonCount; i++)
  1269. {
  1270. delete m_pStrButtonText[i];
  1271. m_pStrButtonText[i] = NULL;
  1272. }
  1273. delete [] m_pStrButtonText;
  1274. m_pStrButtonText = NULL;
  1275. }
  1276. if (m_pnButtonID)
  1277. {
  1278. delete m_pnButtonID;
  1279. m_pnButtonID = NULL;
  1280. }
  1281. m_nButtonCount = 0;
  1282. return S_OK;
  1283. }
  1284. OLECHAR** m_pStrToolTip;
  1285. OLECHAR** m_pStrButtonText;
  1286. UINT* m_pnButtonID;
  1287. UINT m_idToolbar;
  1288. UINT m_nButtonCount;
  1289. };
  1290. #define BEGIN_SNAPINTOOLBARID_MAP(theClass) \
  1291. public: \
  1292. static CSnapInToolbarInfo* GetToolbarInfo() \
  1293. { \
  1294. static CSnapInToolbarInfo m_toolbarInfo[] = \
  1295. {
  1296. #define SNAPINTOOLBARID_ENTRY(id) \
  1297. { NULL, NULL, NULL, id, 0},
  1298. #define END_SNAPINTOOLBARID_MAP() \
  1299. { NULL, NULL, NULL, 0, 0} \
  1300. }; \
  1301. return m_toolbarInfo; \
  1302. }
  1303. template <class T, BOOL bIsExtension = FALSE>
  1304. class ATL_NO_VTABLE CSnapInItemImpl : public CSnapInItem
  1305. {
  1306. public:
  1307. CSnapInItemImpl(unsigned int helpIndex = 0)
  1308. :CSnapInItem(helpIndex)
  1309. {
  1310. }
  1311. virtual ~CSnapInItemImpl()
  1312. {
  1313. }
  1314. public:
  1315. STDMETHOD(Notify)( MMC_NOTIFY_TYPE event,
  1316. LPARAM arg,
  1317. LPARAM param,
  1318. IComponentData* pComponentData,
  1319. IComponent* pComponent,
  1320. DATA_OBJECT_TYPES type)
  1321. {
  1322. ATLASSERT("Override Function in Derived Class");
  1323. ATLTRACENOTIMPL(_T("CSnapInItemImpl::Notify"));
  1324. }
  1325. STDMETHOD(GetScopePaneInfo)(SCOPEDATAITEM *pScopeDataItem)
  1326. {
  1327. ATLTRACENOTIMPL(_T("CSnapInItemImpl::GetScopePaneInfo"));
  1328. }
  1329. STDMETHOD(GetResultViewType)(LPOLESTR *ppViewType,
  1330. long *pViewOptions)
  1331. {
  1332. ATLTRACE(_T("CSnapInItemImpl::GetResultViewType\n"));
  1333. *ppViewType = NULL;
  1334. *pViewOptions = MMC_VIEW_OPTIONS_NONE;
  1335. return S_FALSE;
  1336. }
  1337. STDMETHOD(GetResultPaneInfo)(RESULTDATAITEM *pResultDataItem)
  1338. {
  1339. ATLTRACENOTIMPL(_T("CSnapInItemImpl::GetResultPaneInfo"));
  1340. }
  1341. STDMETHOD(AddMenuItems)(LPCONTEXTMENUCALLBACK piCallback,
  1342. long *pInsertionAllowed,
  1343. DATA_OBJECT_TYPES type)
  1344. {
  1345. ATLTRACE(_T("CSnapInItemImpl::AddMenuItems\n"));
  1346. T* pT = static_cast<T*>(this);
  1347. if (!bIsExtension)
  1348. pT->SetMenuInsertionFlags(true, pInsertionAllowed);
  1349. UINT menuID = pT->GetMenuID();
  1350. if (menuID == 0)
  1351. return S_OK;
  1352. HMENU hMenu = LoadMenu(_Module.GetResourceInstance(), MAKEINTRESOURCE(menuID));
  1353. long insertionID;
  1354. if (hMenu)
  1355. {
  1356. for (int i = 0; 1; i++)
  1357. {
  1358. HMENU hSubMenu = GetSubMenu(hMenu, i);
  1359. if (hSubMenu == NULL)
  1360. break;
  1361. MENUITEMINFO menuItemInfo;
  1362. memset(&menuItemInfo, 0, sizeof(menuItemInfo));
  1363. menuItemInfo.cbSize = sizeof(menuItemInfo);
  1364. switch (i)
  1365. {
  1366. case 0:
  1367. if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP) )
  1368. continue;
  1369. insertionID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  1370. break;
  1371. case 1:
  1372. if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) )
  1373. continue;
  1374. if (bIsExtension)
  1375. insertionID = CCM_INSERTIONPOINTID_3RDPARTY_NEW;
  1376. else
  1377. insertionID = CCM_INSERTIONPOINTID_PRIMARY_NEW;
  1378. break;
  1379. case 2:;
  1380. if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK) )
  1381. continue;
  1382. if (bIsExtension)
  1383. insertionID = CCM_INSERTIONPOINTID_3RDPARTY_TASK;
  1384. else
  1385. insertionID = CCM_INSERTIONPOINTID_PRIMARY_TASK;
  1386. break;
  1387. case 3:;
  1388. if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW) )
  1389. continue;
  1390. insertionID = CCM_INSERTIONPOINTID_PRIMARY_VIEW;
  1391. break;
  1392. default:
  1393. {
  1394. insertionID = 0;
  1395. continue;
  1396. }
  1397. break;
  1398. }
  1399. menuItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
  1400. menuItemInfo.fType = MFT_STRING;
  1401. TCHAR szMenuText[128];
  1402. for (int j = 0; 1; j++)
  1403. {
  1404. menuItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
  1405. menuItemInfo.fType = MFT_STRING;
  1406. menuItemInfo.cch = 128;
  1407. menuItemInfo.dwTypeData = szMenuText;
  1408. TCHAR szStatusBar[256];
  1409. if (!GetMenuItemInfo(hSubMenu, j, TRUE, &menuItemInfo))
  1410. break;
  1411. if (menuItemInfo.fType != MFT_STRING)
  1412. continue;
  1413. pT->UpdateMenuState(menuItemInfo.wID, szMenuText, &menuItemInfo.fState);
  1414. LoadString(_Module.GetResourceInstance(), menuItemInfo.wID, szStatusBar, 256);
  1415. OLECHAR wszStatusBar[256];
  1416. OLECHAR wszMenuText[128];
  1417. USES_CONVERSION;
  1418. ocscpy(wszMenuText, T2OLE(szMenuText));
  1419. ocscpy(wszStatusBar, T2OLE(szStatusBar));
  1420. CONTEXTMENUITEM contextMenuItem;
  1421. contextMenuItem.strName = wszMenuText;
  1422. contextMenuItem.strStatusBarText = wszStatusBar;
  1423. contextMenuItem.lCommandID = menuItemInfo.wID;
  1424. contextMenuItem.lInsertionPointID = insertionID;
  1425. contextMenuItem.fFlags = menuItemInfo.fState;
  1426. contextMenuItem.fSpecialFlags = 0;
  1427. HRESULT hr = piCallback->AddItem(&contextMenuItem);
  1428. ATLASSERT(SUCCEEDED(hr));
  1429. }
  1430. }
  1431. DestroyMenu(hMenu);
  1432. }
  1433. if (!bIsExtension)
  1434. pT->SetMenuInsertionFlags(true, pInsertionAllowed);
  1435. return S_OK;
  1436. }
  1437. STDMETHOD(Command)(long lCommandID,
  1438. CSnapInObjectRootBase* pObj,
  1439. DATA_OBJECT_TYPES type)
  1440. {
  1441. ATLTRACE(_T("CSnapInItemImpl::Command\n"));
  1442. bool bHandled;
  1443. T* pT = static_cast<T*>(this);
  1444. return pT->ProcessCommand(lCommandID, bHandled, pObj, type);
  1445. }
  1446. STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider,
  1447. LONG_PTR handle,
  1448. IUnknown* pUnk,
  1449. DATA_OBJECT_TYPES type)
  1450. {
  1451. ATLASSERT("Override Function in Derived Class");
  1452. ATLTRACENOTIMPL(_T("CSnapInItemImpl::CreatePropertyPages"));
  1453. }
  1454. STDMETHOD(QueryPagesFor)(DATA_OBJECT_TYPES type)
  1455. {
  1456. ATLASSERT("Override Function in Derived Class");
  1457. ATLTRACENOTIMPL(_T("CSnapInItemImpl::QueryPagesFor"));
  1458. }
  1459. STDMETHOD(SetControlbar)(IControlbar *pControlbar,
  1460. IExtendControlbar* pExtendControlBar,
  1461. CSimpleMap<UINT, IUnknown*>* pToolbarMap)
  1462. {
  1463. ATLTRACE(_T("CSnapInItemImpl::SetControlbar\n"));
  1464. T* pT = static_cast<T*>(this);
  1465. CSnapInToolbarInfo* pInfo = pT->GetToolbarInfo();
  1466. if (pInfo == NULL)
  1467. return S_OK;
  1468. for( ; pInfo->m_idToolbar; pInfo++)
  1469. {
  1470. IToolbar* p = (IToolbar*) pToolbarMap->Lookup(pInfo->m_idToolbar);
  1471. if (p != NULL)
  1472. continue;
  1473. HBITMAP hBitmap = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(pInfo->m_idToolbar));
  1474. if (hBitmap == NULL)
  1475. return S_OK;
  1476. HRSRC hRsrc = ::FindResource(_Module.GetResourceInstance(), MAKEINTRESOURCE(pInfo->m_idToolbar), RT_TOOLBAR);
  1477. if (hRsrc == NULL)
  1478. return S_OK;
  1479. HGLOBAL hGlobal = LoadResource(_Module.GetResourceInstance(), hRsrc);
  1480. if (hGlobal == NULL)
  1481. return S_OK;
  1482. CSnapInToolBarData* pData = (CSnapInToolBarData*)LockResource(hGlobal);
  1483. if (pData == NULL)
  1484. return S_OK;
  1485. ATLASSERT(pData->wVersion == 1);
  1486. ATLASSERT(pData->wWidth == 16);
  1487. ATLASSERT(pData->wHeight == 16);
  1488. pInfo->m_nButtonCount = pData->wItemCount;
  1489. if (pInfo->m_pnButtonID == NULL)
  1490. pInfo->m_pnButtonID = new UINT[pInfo->m_nButtonCount];
  1491. if (pInfo->m_pnButtonID == NULL)
  1492. continue;
  1493. MMCBUTTON *pButtons = new MMCBUTTON[pData->wItemCount];
  1494. if (pButtons == NULL)
  1495. {
  1496. delete []pInfo->m_pnButtonID;
  1497. continue;
  1498. }
  1499. if (pInfo->m_pStrToolTip == NULL)
  1500. {
  1501. pInfo->m_pStrToolTip = new OLECHAR* [pData->wItemCount];
  1502. if (pInfo->m_pStrToolTip)
  1503. memset(pInfo->m_pStrToolTip, 0, sizeof(OLECHAR*) * pData->wItemCount);
  1504. }
  1505. if (pInfo->m_pStrToolTip == NULL)
  1506. {
  1507. delete []pInfo->m_pnButtonID;
  1508. delete []pButtons;
  1509. continue;
  1510. }
  1511. for (int i = 0, j = 0; i < pData->wItemCount; i++)
  1512. {
  1513. pInfo->m_pnButtonID[i] = pButtons[i].idCommand = pData->items()[i];
  1514. if (pButtons[i].idCommand)
  1515. {
  1516. pButtons[i].nBitmap = j++;
  1517. // get the statusbar string and allow modification of the button state
  1518. TCHAR szStatusBar[512];
  1519. LoadString(_Module.GetResourceInstance(), pButtons[i].idCommand, szStatusBar, 512);
  1520. if (pInfo->m_pStrToolTip[i] == NULL)
  1521. pInfo->m_pStrToolTip[i] = new OLECHAR[lstrlen(szStatusBar) + 1];
  1522. if (pInfo->m_pStrToolTip[i] == NULL)
  1523. continue;
  1524. USES_CONVERSION;
  1525. ocscpy(pInfo->m_pStrToolTip[i], T2OLE(szStatusBar));
  1526. pButtons[i].lpTooltipText = pInfo->m_pStrToolTip[i];
  1527. pButtons[i].lpButtonText = OLESTR("");
  1528. pButtons[i].fsState = TBSTATE_ENABLED;
  1529. pButtons[i].fsType = TBSTYLE_BUTTON;
  1530. pT->SetToolbarButtonInfo(pButtons[i].idCommand, &pButtons[i].fsState, &pButtons[i].fsType);
  1531. }
  1532. else
  1533. {
  1534. pButtons[i].lpTooltipText = OLESTR("");
  1535. pButtons[i].lpButtonText = OLESTR("");
  1536. pButtons[i].fsType = TBSTYLE_SEP;
  1537. pButtons[i].fsState = 0;
  1538. }
  1539. }
  1540. IToolbar* pToolbar;
  1541. HRESULT hr = pControlbar->Create(TOOLBAR, pExtendControlBar, reinterpret_cast<LPUNKNOWN*>(&pToolbar));
  1542. if (SUCCEEDED(hr))
  1543. {
  1544. hr = pToolbar->AddBitmap(pData->wItemCount, hBitmap, pData->wWidth, pData->wHeight, RGB(255, 0, 255));
  1545. if (SUCCEEDED(hr))
  1546. {
  1547. hr = pToolbar->AddButtons(pData->wItemCount, pButtons);
  1548. if (SUCCEEDED(hr))
  1549. {
  1550. pToolbar->AddRef();
  1551. pToolbarMap->Add(pInfo->m_idToolbar, (IUnknown*)pToolbar);
  1552. }
  1553. }
  1554. }
  1555. pToolbar->Release();
  1556. delete [] pButtons;
  1557. }
  1558. return S_OK;
  1559. }
  1560. STDMETHOD(ControlbarNotify)(IControlbar *pControlbar,
  1561. IExtendControlbar *pExtendControlbar,
  1562. CSimpleMap<UINT, IUnknown*>* pToolbarMap,
  1563. MMC_NOTIFY_TYPE event,
  1564. LPARAM arg,
  1565. LPARAM param,
  1566. CSnapInObjectRootBase* pObj,
  1567. DATA_OBJECT_TYPES type)
  1568. {
  1569. ATLTRACE(_T("CSnapInItemImpl::ControlbarNotify\n"));
  1570. T* pT = static_cast<T*>(this);
  1571. SetControlbar(pControlbar, pExtendControlbar, pToolbarMap);
  1572. if(event == MMCN_SELECT)
  1573. {
  1574. if (pControlbar == NULL)
  1575. return S_OK;
  1576. BOOL bSelect = (BOOL) HIWORD (arg);
  1577. BOOL bScope = (BOOL) LOWORD(arg);
  1578. CSnapInToolbarInfo* pInfo = pT->GetToolbarInfo();
  1579. if (pInfo == NULL)
  1580. return S_OK;
  1581. for(; pInfo->m_idToolbar; pInfo++)
  1582. {
  1583. IToolbar* pToolbar = (IToolbar*)pToolbarMap->Lookup(pInfo->m_idToolbar);
  1584. if (pToolbar == NULL)
  1585. continue;
  1586. if (!bSelect && bScope)
  1587. pControlbar->Detach(pToolbar);
  1588. else
  1589. {
  1590. pControlbar->Attach(TOOLBAR, pToolbar);
  1591. for (UINT i = 0; i < pInfo->m_nButtonCount; i++)
  1592. {
  1593. if (pInfo->m_pnButtonID[i])
  1594. {
  1595. pToolbar->SetButtonState(pInfo->m_pnButtonID[i],
  1596. ENABLED,
  1597. pT->UpdateToolbarButton(pInfo->m_pnButtonID[i],
  1598. ENABLED));
  1599. pToolbar->SetButtonState(pInfo->m_pnButtonID[i],
  1600. CHECKED,
  1601. pT->UpdateToolbarButton(pInfo->m_pnButtonID[i],
  1602. CHECKED));
  1603. pToolbar->SetButtonState(pInfo->m_pnButtonID[i],
  1604. HIDDEN,
  1605. pT->UpdateToolbarButton(pInfo->m_pnButtonID[i],
  1606. HIDDEN));
  1607. pToolbar->SetButtonState(pInfo->m_pnButtonID[i],
  1608. INDETERMINATE,
  1609. pT->UpdateToolbarButton(pInfo->m_pnButtonID[i],
  1610. INDETERMINATE));
  1611. pToolbar->SetButtonState(pInfo->m_pnButtonID[i],
  1612. BUTTONPRESSED,
  1613. pT->UpdateToolbarButton(pInfo->m_pnButtonID[i],
  1614. BUTTONPRESSED));
  1615. }
  1616. }
  1617. }
  1618. }
  1619. return S_OK;
  1620. }
  1621. else if (event == MMCN_BTN_CLICK)
  1622. {
  1623. bool bHandled;
  1624. return pT->ProcessCommand((UINT) param, bHandled, pObj, type);
  1625. }
  1626. return E_UNEXPECTED;
  1627. }
  1628. STDMETHOD(GetScopeData)(SCOPEDATAITEM **pScopeDataItem)
  1629. {
  1630. if (pScopeDataItem == NULL)
  1631. return E_FAIL;
  1632. *pScopeDataItem = &m_scopeDataItem;
  1633. return S_OK;
  1634. }
  1635. STDMETHOD(GetResultData)(RESULTDATAITEM **pResultDataItem)
  1636. {
  1637. if (pResultDataItem == NULL)
  1638. return E_FAIL;
  1639. *pResultDataItem = &m_resultDataItem;
  1640. return S_OK;
  1641. }
  1642. STDMETHOD(GetDataObject)(IDataObject** pDataObj, DATA_OBJECT_TYPES type)
  1643. {
  1644. CComObject<CSnapInDataObjectImpl>* pData;
  1645. HRESULT hr = CComObject<CSnapInDataObjectImpl>::CreateInstance(&pData);
  1646. if (FAILED(hr))
  1647. return hr;
  1648. T* pT = static_cast<T*> (this);
  1649. pData->m_objectData.m_pItem = pT;
  1650. pData->m_objectData.m_type = type;
  1651. hr = pData->QueryInterface(IID_IDataObject, (void**)(pDataObj));
  1652. return hr;
  1653. }
  1654. void UpdateMenuState(UINT id, LPTSTR pBuf, UINT *flags)
  1655. {
  1656. return;
  1657. }
  1658. void SetToolbarButtonInfo(UINT id, BYTE *pfsState, BYTE *pfsType)
  1659. {
  1660. *pfsState = TBSTATE_ENABLED;
  1661. *pfsType = TBSTYLE_BUTTON;
  1662. }
  1663. BOOL UpdateToolbarButton(UINT id, BYTE fsState)
  1664. {
  1665. if (fsState == ENABLED)
  1666. return TRUE;
  1667. return FALSE;
  1668. }
  1669. HRESULT ProcessCommand(UINT nID,
  1670. bool& bHandled,
  1671. CSnapInObjectRootBase* pObj,
  1672. DATA_OBJECT_TYPES type)
  1673. {
  1674. ATLTRACE(_T("No handler for item with ID %d\n"), nID);
  1675. return S_OK;
  1676. }
  1677. STDMETHOD (FillData)(CLIPFORMAT cf, LPSTREAM pStream)
  1678. {
  1679. HRESULT hr = DV_E_CLIPFORMAT;
  1680. ULONG uWritten;
  1681. T* pT = static_cast<T*> (this);
  1682. if (cf == m_CCF_NODETYPE)
  1683. {
  1684. hr = pStream->Write(pT->GetNodeType(), sizeof(GUID), &uWritten);
  1685. return hr;
  1686. }
  1687. if (cf == m_CCF_SZNODETYPE)
  1688. {
  1689. hr = pStream->Write(pT->GetSZNodeType(), (ocslen((OLECHAR*)pT->GetSZNodeType()) + 1 )* sizeof(OLECHAR), &uWritten);
  1690. return hr;
  1691. }
  1692. if (cf == m_CCF_DISPLAY_NAME)
  1693. {
  1694. hr = pStream->Write(pT->GetDisplayName(), (ocslen((OLECHAR*)pT->GetDisplayName()) + 1) * sizeof(OLECHAR), &uWritten);
  1695. return hr;
  1696. }
  1697. if (cf == m_CCF_SNAPIN_CLASSID)
  1698. {
  1699. hr = pStream->Write(pT->GetSnapInCLSID(), sizeof(GUID), &uWritten);
  1700. return hr;
  1701. }
  1702. return hr;
  1703. }
  1704. static CSnapInToolbarInfo* GetToolbarInfo()
  1705. {
  1706. return NULL;
  1707. }
  1708. static const UINT GetMenuID()
  1709. {
  1710. return 0;
  1711. }
  1712. void SetMenuInsertionFlags(bool bBeforeInsertion, long* pInsertionAllowed)
  1713. {
  1714. }
  1715. void* GetNodeType()
  1716. {
  1717. return (void*)T::m_NODETYPE;
  1718. }
  1719. void* GetSZNodeType()
  1720. {
  1721. return (void*)T::m_SZNODETYPE;
  1722. }
  1723. void* GetDisplayName()
  1724. {
  1725. return (void*)T::m_SZDISPLAY_NAME;
  1726. }
  1727. void* GetSnapInCLSID()
  1728. {
  1729. return (void*)T::m_SNAPIN_CLASSID;
  1730. }
  1731. CComBSTR m_bstrDisplayName;
  1732. SCOPEDATAITEM m_scopeDataItem;
  1733. RESULTDATAITEM m_resultDataItem;
  1734. #ifdef TASKPAD_SUPPORT
  1735. STDMETHOD(TaskNotify)(
  1736. IDataObject * pDataObject
  1737. , VARIANT * pvarg
  1738. , VARIANT * pvparam
  1739. )
  1740. {
  1741. ATLTRACENOTIMPL(_T("CSnapInItemImpl::TaskNotify"));
  1742. }
  1743. STDMETHOD(EnumTasks)(
  1744. IDataObject * pDataObject
  1745. , BSTR szTaskGroup
  1746. , IEnumTASK** ppEnumTASK
  1747. )
  1748. {
  1749. ATLTRACENOTIMPL(_T("CSnapInItemImpl::EnumTasks"));
  1750. }
  1751. #endif // TASKPAD_SUPPORT
  1752. };
  1753. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_NODETYPE = 0;
  1754. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_SZNODETYPE = 0;
  1755. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_DISPLAY_NAME = 0;
  1756. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_SNAPIN_CLASSID = 0;
  1757. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_SNAPIN_GETOBJECTDATA = 0;
  1758. _declspec( selectany ) CLIPFORMAT CSnapInItem::m_CCF_MMC_MULTISELECT_DATAOBJECT = 0;
  1759. #endif //__ATL_SNAPIN_H__