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.

1800 lines
43 KiB

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