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

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