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.

1925 lines
47 KiB

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