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.

1608 lines
38 KiB

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