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.

807 lines
19 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: benefits.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #ifndef __BENEFITS_H_
  11. #define __BENEFITS_H_
  12. #include "resource.h"
  13. #include <atlsnap.h>
  14. #include "snaphelp.h"
  15. #include "atltask.h"
  16. #include "BenSvr.h"
  17. #include "Employee.h"
  18. //
  19. // Property page containing employee information.
  20. //
  21. class CEmployeeNamePage : public CSnapInPropertyPageImpl<CEmployeeNamePage>
  22. {
  23. public :
  24. CEmployeeNamePage(long lNotifyHandle, bool fStartup, bool bDeleteHandle = false, TCHAR* pTitle = NULL) :
  25. CSnapInPropertyPageImpl<CEmployeeNamePage> (pTitle),\
  26. m_fStartup( fStartup ),
  27. m_lNotifyHandle(lNotifyHandle),
  28. m_bDeleteHandle(bDeleteHandle) // Should be true for only page.
  29. {
  30. m_pEmployee = NULL;
  31. }
  32. ~CEmployeeNamePage()
  33. {
  34. if (m_bDeleteHandle)
  35. MMCFreeNotifyHandle(m_lNotifyHandle);
  36. }
  37. enum { IDD = IDD_NAME_PAGE };
  38. BEGIN_MSG_MAP(CEmployeeNamePage)
  39. MESSAGE_HANDLER( WM_INITDIALOG, OnInitDialog )
  40. COMMAND_CODE_HANDLER( EN_CHANGE, OnChange )
  41. CHAIN_MSG_MAP(CSnapInPropertyPageImpl<CEmployeeNamePage>)
  42. END_MSG_MAP()
  43. HRESULT PropertyChangeNotify(long param)
  44. {
  45. return MMCPropertyChangeNotify(m_lNotifyHandle, param);
  46. }
  47. //
  48. // Handler to initialize values in dialog.
  49. //
  50. LRESULT OnInitDialog( UINT uiMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled );
  51. //
  52. // Calls OnWizardFinish() to handle the storage of employee
  53. // data.
  54. //
  55. BOOL OnApply() { return( OnWizardFinish() ); };
  56. //
  57. // Calls OnWizardFinish() to handle the storage of employee
  58. // data.
  59. //
  60. BOOL OnWizardNext() { return( OnWizardFinish() ); };
  61. //
  62. // This is overridden to modify the UI depending on whether
  63. // we're in start-up mode or not.
  64. //
  65. BOOL OnSetActive();
  66. //
  67. // Overridden to store new values of employee.
  68. //
  69. BOOL OnWizardFinish();
  70. //
  71. // Called when one of the values has been modified. We need
  72. // to inform the property page of the change.
  73. //
  74. LRESULT OnChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  75. {
  76. UNUSED_ALWAYS( wNotifyCode );
  77. UNUSED_ALWAYS( wID );
  78. UNUSED_ALWAYS( hWndCtl );
  79. UNUSED_ALWAYS( bHandled );
  80. SetModified();
  81. return( TRUE );
  82. }
  83. public:
  84. long m_lNotifyHandle;
  85. bool m_bDeleteHandle;
  86. CEmployee* m_pEmployee;
  87. bool m_fStartup;
  88. };
  89. //
  90. // Property page containing employee information.
  91. //
  92. class CEmployeeAddressPage : public CSnapInPropertyPageImpl<CEmployeeAddressPage>
  93. {
  94. public :
  95. CEmployeeAddressPage(long lNotifyHandle, bool fStartup, bool bDeleteHandle = false, TCHAR* pTitle = NULL) :
  96. CSnapInPropertyPageImpl<CEmployeeAddressPage> (pTitle),\
  97. m_fStartup( fStartup ),
  98. m_lNotifyHandle(lNotifyHandle),
  99. m_bDeleteHandle(bDeleteHandle) // Should be true for only page.
  100. {
  101. m_pEmployee = NULL;
  102. }
  103. ~CEmployeeAddressPage()
  104. {
  105. if (m_bDeleteHandle)
  106. MMCFreeNotifyHandle(m_lNotifyHandle);
  107. }
  108. enum { IDD = IDD_ADDRESS_PAGE };
  109. BEGIN_MSG_MAP(CEmployeeAddressPage)
  110. MESSAGE_HANDLER( WM_INITDIALOG, OnInitDialog )
  111. COMMAND_CODE_HANDLER( EN_CHANGE, OnChange )
  112. CHAIN_MSG_MAP(CSnapInPropertyPageImpl<CEmployeeAddressPage>)
  113. END_MSG_MAP()
  114. // Handler prototypes:
  115. // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  116. // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  117. // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
  118. HRESULT PropertyChangeNotify(long param)
  119. {
  120. return MMCPropertyChangeNotify(m_lNotifyHandle, param);
  121. }
  122. //
  123. // Handler to initialize values in dialog.
  124. //
  125. LRESULT OnInitDialog( UINT uiMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled );
  126. //
  127. // Calls OnWizardFinish() to handle the storage of employee
  128. // data.
  129. //
  130. BOOL OnApply() { return( OnWizardFinish() ); };
  131. //
  132. // This is overridden to modify the UI depending on whether
  133. // we're in start-up mode or not.
  134. //
  135. BOOL OnSetActive();
  136. //
  137. // Overridden to store new values of employee.
  138. //
  139. BOOL OnWizardFinish();
  140. //
  141. // Called when one of the values has been modified. We need
  142. // to inform the property page of the change.
  143. //
  144. LRESULT OnChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  145. {
  146. UNUSED_ALWAYS( wNotifyCode );
  147. UNUSED_ALWAYS( wID );
  148. UNUSED_ALWAYS( hWndCtl );
  149. UNUSED_ALWAYS( bHandled );
  150. SetModified();
  151. return( TRUE );
  152. }
  153. public:
  154. long m_lNotifyHandle;
  155. bool m_bDeleteHandle;
  156. CEmployee* m_pEmployee;
  157. bool m_fStartup;
  158. };
  159. template< class T >
  160. class CBenefitsData : public CSnapInItemImpl< T >
  161. {
  162. public:
  163. static const GUID* m_NODETYPE;
  164. static const TCHAR* m_SZNODETYPE;
  165. static const TCHAR* m_SZDISPLAY_NAME;
  166. static const CLSID* m_SNAPIN_CLASSID;
  167. CBenefitsData( CEmployee* pEmployee )
  168. {
  169. //
  170. // Assign the given employee to our internal containment.
  171. // This employee will be assumed valid for the lifetime of
  172. // this object since persistence is maintained by our parent
  173. // node.
  174. //
  175. m_pEmployee = pEmployee;
  176. //
  177. // Always initialize our display name with the static declared.
  178. //
  179. m_bstrDisplayName = m_SZDISPLAY_NAME;
  180. //
  181. // Image indexes may need to be modified depending on the images specific to
  182. // the snapin.
  183. //
  184. memset(&m_scopeDataItem, 0, sizeof(SCOPEDATAITEM));
  185. m_scopeDataItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM;
  186. m_scopeDataItem.displayname = MMC_CALLBACK;
  187. m_scopeDataItem.nImage = 0; // May need modification
  188. m_scopeDataItem.nOpenImage = 0; // May need modification
  189. m_scopeDataItem.lParam = (LPARAM) this;
  190. memset(&m_resultDataItem, 0, sizeof(RESULTDATAITEM));
  191. m_resultDataItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  192. m_resultDataItem.str = MMC_CALLBACK;
  193. m_resultDataItem.nImage = 0; // May need modification
  194. m_resultDataItem.lParam = (LPARAM) this;
  195. }
  196. ~CBenefitsData()
  197. {
  198. }
  199. STDMETHOD(GetScopePaneInfo)(SCOPEDATAITEM *pScopeDataItem)
  200. {
  201. if (pScopeDataItem->mask & SDI_STR)
  202. pScopeDataItem->displayname = m_bstrDisplayName;
  203. if (pScopeDataItem->mask & SDI_IMAGE)
  204. pScopeDataItem->nImage = m_scopeDataItem.nImage;
  205. if (pScopeDataItem->mask & SDI_OPENIMAGE)
  206. pScopeDataItem->nOpenImage = m_scopeDataItem.nOpenImage;
  207. if (pScopeDataItem->mask & SDI_PARAM)
  208. pScopeDataItem->lParam = m_scopeDataItem.lParam;
  209. if (pScopeDataItem->mask & SDI_STATE )
  210. pScopeDataItem->nState = m_scopeDataItem.nState;
  211. //
  212. // SDI_CHILDREN should be overridden by its derived classes.
  213. //
  214. return S_OK;
  215. }
  216. STDMETHOD(GetResultPaneInfo)(RESULTDATAITEM *pResultDataItem)
  217. {
  218. if (pResultDataItem->bScopeItem)
  219. {
  220. if (pResultDataItem->mask & RDI_STR)
  221. {
  222. pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol);
  223. }
  224. if (pResultDataItem->mask & RDI_IMAGE)
  225. {
  226. pResultDataItem->nImage = m_scopeDataItem.nImage;
  227. }
  228. if (pResultDataItem->mask & RDI_PARAM)
  229. {
  230. pResultDataItem->lParam = m_scopeDataItem.lParam;
  231. }
  232. return S_OK;
  233. }
  234. if (pResultDataItem->mask & RDI_STR)
  235. {
  236. pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol);
  237. }
  238. if (pResultDataItem->mask & RDI_IMAGE)
  239. {
  240. pResultDataItem->nImage = m_resultDataItem.nImage;
  241. }
  242. if (pResultDataItem->mask & RDI_PARAM)
  243. {
  244. pResultDataItem->lParam = m_resultDataItem.lParam;
  245. }
  246. if (pResultDataItem->mask & RDI_INDEX)
  247. {
  248. pResultDataItem->nIndex = m_resultDataItem.nIndex;
  249. }
  250. return S_OK;
  251. }
  252. //
  253. // Overridden to provide result icons.
  254. //
  255. STDMETHOD( OnAddImages )( MMC_NOTIFY_TYPE event,
  256. long arg,
  257. long param,
  258. IConsole* pConsole,
  259. DATA_OBJECT_TYPES type )
  260. {
  261. UNUSED_ALWAYS( event );
  262. UNUSED_ALWAYS( param );
  263. UNUSED_ALWAYS( pConsole );
  264. UNUSED_ALWAYS( type );
  265. // Add Images
  266. IImageList* pImageList = (IImageList*) arg;
  267. HRESULT hr = E_FAIL;
  268. // Load bitmaps associated with the scope pane
  269. // and add them to the image list
  270. // Loads the default bitmaps generated by the wizard
  271. // Change as required
  272. HBITMAP hBitmap16 = LoadBitmap( _Module.GetResourceInstance(), MAKEINTRESOURCE( IDB_BENEFITS_16 ) );
  273. if (hBitmap16 != NULL)
  274. {
  275. HBITMAP hBitmap32 = LoadBitmap( _Module.GetResourceInstance(), MAKEINTRESOURCE( IDB_BENEFITS_32 ) );
  276. if (hBitmap32 != NULL)
  277. {
  278. hr = pImageList->ImageListSetStrip( (long*)hBitmap16,
  279. (long*) hBitmap32, 0, RGB( 0, 128, 128 ) );
  280. if ( FAILED( hr ) )
  281. ATLTRACE( _T( "IImageList::ImageListSetStrip failed\n" ) );
  282. }
  283. }
  284. return( hr );
  285. }
  286. virtual LPOLESTR GetResultPaneColInfo(int nCol)
  287. {
  288. if (nCol == 0)
  289. {
  290. T* pT = static_cast<T*>(this);
  291. return( pT->m_bstrDisplayName );
  292. }
  293. // TODO : Return the text for other columns
  294. return OLESTR("Generic Description");
  295. }
  296. //
  297. // Helper function to extract the appropriate console from
  298. // a base object type.
  299. //
  300. STDMETHOD( GetConsole )( CSnapInObjectRootBase* pObj, IConsole** ppConsole )
  301. {
  302. HRESULT hr = E_FAIL;
  303. if ( pObj->m_nType == 1 )
  304. {
  305. //
  306. // This is the id of the data object.
  307. //
  308. *ppConsole = ( (CBenefits*) pObj )->m_spConsole;
  309. (*ppConsole)->AddRef();
  310. hr = S_OK;
  311. }
  312. else if ( pObj->m_nType == 2 )
  313. {
  314. //
  315. // This is the id of the component object.
  316. //
  317. *ppConsole = ( (CBenefitsComponent*) pObj )->m_spConsole;
  318. (*ppConsole)->AddRef();
  319. hr = S_OK;
  320. }
  321. return( hr );
  322. }
  323. //
  324. // Called to determine if the clipboard data can be obtained and
  325. // if it has a node type that matches the given GUID.
  326. //
  327. STDMETHOD( IsClipboardDataType )( LPDATAOBJECT pDataObject, GUID inGuid )
  328. {
  329. HRESULT hr = S_FALSE;
  330. if ( pDataObject == NULL )
  331. return( E_POINTER );
  332. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  333. FORMATETC formatetc = { CSnapInItem::m_CCF_NODETYPE,
  334. NULL,
  335. DVASPECT_CONTENT,
  336. -1,
  337. TYMED_HGLOBAL
  338. };
  339. //
  340. // Allocate memory to received the GUID.
  341. //
  342. stgmedium.hGlobal = GlobalAlloc( 0, sizeof( GUID ) );
  343. if ( stgmedium.hGlobal == NULL )
  344. return( E_OUTOFMEMORY );
  345. //
  346. // Retrieve the GUID of the paste object.
  347. //
  348. hr = pDataObject->GetDataHere( &formatetc, &stgmedium );
  349. if( FAILED( hr ) )
  350. {
  351. GlobalFree(stgmedium.hGlobal);
  352. return( hr );
  353. }
  354. //
  355. // Make a local copy of the GUID.
  356. //
  357. GUID guid;
  358. memcpy( &guid, stgmedium.hGlobal, sizeof( GUID ) );
  359. GlobalFree( stgmedium.hGlobal );
  360. //
  361. // Check to see if the node is of the appropriate type.
  362. //
  363. if ( IsEqualGUID( guid, inGuid ) )
  364. hr = S_OK;
  365. else
  366. hr = S_FALSE;
  367. return( hr );
  368. }
  369. //
  370. // Command handler for "OnImport" functionality. For the current
  371. // sample, display a simple message box.
  372. //
  373. STDMETHOD( OnImport )(bool& bHandled, CSnapInObjectRootBase* pObj)
  374. {
  375. UNUSED_ALWAYS( bHandled );
  376. USES_CONVERSION;
  377. int nResult;
  378. CComPtr<IConsole> spConsole;
  379. //
  380. // Retrieve the appropriate console.
  381. //
  382. GetConsole( pObj, &spConsole );
  383. spConsole->MessageBox( T2OLE( _T( "Data successfully imported" ) ),
  384. T2OLE( _T( "Benefits" ) ),
  385. MB_ICONINFORMATION | MB_OK,
  386. &nResult );
  387. return( S_OK );
  388. };
  389. //
  390. // Command handler for "OnExport" functionality. For the current
  391. // sample, display a simple message box.
  392. //
  393. STDMETHOD( OnExport )(bool& bHandled, CSnapInObjectRootBase* pObj)
  394. {
  395. UNUSED_ALWAYS( bHandled );
  396. USES_CONVERSION;
  397. int nResult;
  398. CComPtr<IConsole> spConsole;
  399. //
  400. // Retrieve the appropriate console.
  401. //
  402. GetConsole( pObj, &spConsole );
  403. spConsole->MessageBox( T2OLE( _T( "Data successfully exported" ) ),
  404. T2OLE( _T( "Benefits" ) ),
  405. MB_ICONINFORMATION | MB_OK,
  406. &nResult );
  407. return( S_OK );
  408. };
  409. protected:
  410. //
  411. // Container for the employee information.
  412. //
  413. CEmployee* m_pEmployee;
  414. };
  415. template< class T >
  416. class CChildrenBenefitsData : public CBenefitsData< T >
  417. {
  418. public:
  419. //
  420. // Call the benefits data with no employee. All of our
  421. // containment nodes are not passed in an employee.
  422. //
  423. CChildrenBenefitsData< T >( CEmployee* pEmployee = NULL ) : CBenefitsData< T >( pEmployee )
  424. {
  425. };
  426. //
  427. // Overridden to automatically clean-up any child nodes.
  428. //
  429. virtual ~CChildrenBenefitsData()
  430. {
  431. //
  432. // Free any added nodes.
  433. //
  434. for ( int i = 0; i < m_Nodes.GetSize(); i++ )
  435. {
  436. CSnapInItem* pNode;
  437. pNode = m_Nodes[ i ];
  438. _ASSERTE( pNode != NULL );
  439. delete pNode;
  440. }
  441. }
  442. //
  443. // Overridden to automatically expand any child nodes.
  444. //
  445. STDMETHOD( OnShow )( MMC_NOTIFY_TYPE event,
  446. long arg,
  447. long param,
  448. IConsole* pConsole,
  449. DATA_OBJECT_TYPES type)
  450. {
  451. UNUSED_ALWAYS( event );
  452. UNUSED_ALWAYS( param );
  453. UNUSED_ALWAYS( type );
  454. HRESULT hr = E_NOTIMPL;
  455. ATLTRACE2(atlTraceSnapin, 0, _T("CChildNodeImpl::OnExpand\n"));
  456. //
  457. // Only add the items if we're being selected.
  458. //
  459. if ( arg == TRUE )
  460. {
  461. CComQIPtr<IResultData,&IID_IResultData> spResultData( pConsole );
  462. //
  463. // Loop through and add each subnode.
  464. //
  465. for ( int i = 0; i < m_Nodes.GetSize(); i++ )
  466. {
  467. CSnapInItem* pNode;
  468. RESULTDATAITEM* pResultData;
  469. pNode = m_Nodes[ i ];
  470. _ASSERTE( pNode != NULL );
  471. //
  472. // Get the scope pane info for the node and set
  473. // relative id.
  474. //
  475. pNode->GetResultData( &pResultData );
  476. _ASSERTE( pResultData != NULL );
  477. //
  478. // Add the item to the scope list using the newly
  479. // populated scope data item.
  480. //
  481. hr = spResultData->InsertItem( pResultData );
  482. _ASSERTE( SUCCEEDED( hr ) );
  483. }
  484. }
  485. return( hr );
  486. };
  487. //
  488. // Overridden to automatically expand any child nodes.
  489. //
  490. STDMETHOD( OnExpand )( MMC_NOTIFY_TYPE event,
  491. long arg,
  492. long param,
  493. IConsole* pConsole,
  494. DATA_OBJECT_TYPES type)
  495. {
  496. UNUSED_ALWAYS( event );
  497. UNUSED_ALWAYS( arg );
  498. UNUSED_ALWAYS( type );
  499. ATLTRACE2(atlTraceSnapin, 0, _T("CChildNodeImpl::OnExpand\n"));
  500. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> pNameSpace( pConsole );
  501. HRESULT hr = E_NOTIMPL;
  502. //
  503. // Loop through and add each subnode.
  504. //
  505. for ( int i = 0; i < m_Nodes.GetSize(); i++ )
  506. {
  507. CSnapInItem* pNode;
  508. SCOPEDATAITEM* pScopeData;
  509. pNode = m_Nodes[ i ];
  510. _ASSERTE( pNode != NULL );
  511. //
  512. // Get the scope pane info for the node and set
  513. // relative id.
  514. //
  515. pNode->GetScopeData( &pScopeData );
  516. _ASSERTE( pScopeData != NULL );
  517. pScopeData->relativeID = param;
  518. //
  519. // Add the item to the scope list using the newly
  520. // populated scope data item.
  521. //
  522. hr = pNameSpace->InsertItem( pScopeData );
  523. _ASSERTE( SUCCEEDED( hr ) );
  524. }
  525. return( hr );
  526. };
  527. //
  528. // Used as containment for all child nodes.
  529. //
  530. CSimpleArray<CSnapInItem*> m_Nodes;
  531. };
  532. class CBenefits;
  533. class CBenefitsComponent : public CComObjectRootEx<CComSingleThreadModel>,
  534. public CSnapInObjectRoot<2, CBenefits >,
  535. public IExtendPropertySheetImpl<CBenefitsComponent>,
  536. public IExtendContextMenuImpl<CBenefitsComponent>,
  537. public IExtendControlbarImpl<CBenefitsComponent>,
  538. public IComponentImpl<CBenefitsComponent>,
  539. public IExtendTaskPadImpl<CBenefitsComponent>
  540. {
  541. public:
  542. BEGIN_COM_MAP(CBenefitsComponent)
  543. COM_INTERFACE_ENTRY(IComponent)
  544. COM_INTERFACE_ENTRY(IExtendPropertySheet)
  545. COM_INTERFACE_ENTRY(IExtendContextMenu)
  546. COM_INTERFACE_ENTRY(IExtendControlbar)
  547. COM_INTERFACE_ENTRY(IExtendTaskPad)
  548. END_COM_MAP()
  549. public:
  550. CBenefitsComponent()
  551. {
  552. //
  553. // Taskpad initialization stuff.
  554. //
  555. m_pszTitle = L"Benefits Taskpad";
  556. m_pszBackgroundPath = NULL;
  557. }
  558. STDMETHOD(Notify)(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, long arg, long param)
  559. {
  560. if (lpDataObject != NULL)
  561. return IComponentImpl<CBenefitsComponent>::Notify(lpDataObject, event, arg, param);
  562. return E_NOTIMPL;
  563. }
  564. //
  565. // Taskpad related information. Specifies titles, background
  566. // information, etc.
  567. //
  568. LPOLESTR m_pszTitle;
  569. LPOLESTR m_pszBackgroundPath;
  570. };
  571. class CBenefits : public CComObjectRootEx<CComSingleThreadModel>,
  572. public CSnapInObjectRoot<1, CBenefits>,
  573. public IComponentDataImpl<CBenefits, CBenefitsComponent>,
  574. public IExtendPropertySheetImpl<CBenefits>,
  575. public IExtendContextMenuImpl<CBenefits>,
  576. public IPersistStream,
  577. public CComCoClass<CBenefits, &CLSID_Benefits>,
  578. public ISnapinHelpImpl<CBenefits>
  579. {
  580. public:
  581. CBenefits();
  582. ~CBenefits();
  583. BEGIN_COM_MAP(CBenefits)
  584. COM_INTERFACE_ENTRY(IComponentData)
  585. COM_INTERFACE_ENTRY(IExtendPropertySheet)
  586. COM_INTERFACE_ENTRY(IExtendContextMenu)
  587. COM_INTERFACE_ENTRY(IPersistStream)
  588. COM_INTERFACE_ENTRY(ISnapinHelp)
  589. END_COM_MAP()
  590. DECLARE_REGISTRY_RESOURCEID(IDR_BENEFITS)
  591. DECLARE_NOT_AGGREGATABLE(CBenefits)
  592. //
  593. // Return the classid of this object.
  594. //
  595. STDMETHOD(GetClassID)(CLSID *pClassID)
  596. {
  597. *pClassID = GetObjectCLSID();
  598. return S_OK;
  599. }
  600. //
  601. // Call the root node's implementation.
  602. //
  603. STDMETHOD(IsDirty)();
  604. //
  605. // Call the root node's implementation.
  606. //
  607. STDMETHOD(Load)(LPSTREAM pStm);
  608. //
  609. // Call the root node's implementation.
  610. //
  611. STDMETHOD(Save)(LPSTREAM pStm, BOOL fClearDirty);
  612. //
  613. // Call the root node's implementation.
  614. //
  615. STDMETHOD(GetSizeMax)(ULARGE_INTEGER FAR* pcbSize );
  616. STDMETHOD(Initialize)(LPUNKNOWN pUnknown);
  617. static void WINAPI ObjectMain(bool bStarting)
  618. {
  619. if (bStarting)
  620. CSnapInItem::Init();
  621. }
  622. //
  623. // This is overridden to handle update notifications from
  624. // the property pages.
  625. //
  626. STDMETHOD(Notify)(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, long arg, long param);
  627. };
  628. class ATL_NO_VTABLE CBenefitsAbout : public ISnapinAbout,
  629. public CComObjectRoot,
  630. public CComCoClass< CBenefitsAbout, &CLSID_BenefitsAbout>
  631. {
  632. public:
  633. DECLARE_REGISTRY(CBenefitsAbout, _T("BenefitsAbout.1"), _T("BenefitsAbout.1"), IDS_BENEFITS_DESC, THREADFLAGS_BOTH);
  634. BEGIN_COM_MAP(CBenefitsAbout)
  635. COM_INTERFACE_ENTRY(ISnapinAbout)
  636. END_COM_MAP()
  637. STDMETHOD(GetSnapinDescription)(LPOLESTR *lpDescription)
  638. {
  639. USES_CONVERSION;
  640. TCHAR szBuf[256];
  641. if (::LoadString(_Module.GetResourceInstance(), IDS_BENEFITS_DESC, szBuf, 256) == 0)
  642. return E_FAIL;
  643. *lpDescription = (LPOLESTR)CoTaskMemAlloc((lstrlen(szBuf) + 1) * sizeof(OLECHAR));
  644. if (*lpDescription == NULL)
  645. return E_OUTOFMEMORY;
  646. ocscpy(*lpDescription, T2OLE(szBuf));
  647. return S_OK;
  648. }
  649. STDMETHOD(GetProvider)(LPOLESTR *lpName)
  650. {
  651. USES_CONVERSION;
  652. TCHAR szBuf[256];
  653. if (::LoadString(_Module.GetResourceInstance(), IDS_BENEFITS_PROVIDER, szBuf, 256) == 0)
  654. return E_FAIL;
  655. *lpName = (LPOLESTR)CoTaskMemAlloc((lstrlen(szBuf) + 1) * sizeof(OLECHAR));
  656. if (*lpName == NULL)
  657. return E_OUTOFMEMORY;
  658. ocscpy(*lpName, T2OLE(szBuf));
  659. return S_OK;
  660. }
  661. STDMETHOD(GetSnapinVersion)(LPOLESTR *lpVersion)
  662. {
  663. USES_CONVERSION;
  664. TCHAR szBuf[256];
  665. if (::LoadString(_Module.GetResourceInstance(), IDS_BENEFITS_VERSION, szBuf, 256) == 0)
  666. return E_FAIL;
  667. *lpVersion = (LPOLESTR)CoTaskMemAlloc((lstrlen(szBuf) + 1) * sizeof(OLECHAR));
  668. if (*lpVersion == NULL)
  669. return E_OUTOFMEMORY;
  670. ocscpy(*lpVersion, T2OLE(szBuf));
  671. return S_OK;
  672. }
  673. STDMETHOD(GetSnapinImage)(HICON *hAppIcon)
  674. {
  675. *hAppIcon = NULL;
  676. return S_OK;
  677. }
  678. STDMETHOD(GetStaticFolderImage)(HBITMAP *hSmallImage,
  679. HBITMAP *hSmallImageOpen,
  680. HBITMAP *hLargeImage,
  681. COLORREF *cMask)
  682. {
  683. UNUSED_ALWAYS( hSmallImage );
  684. UNUSED_ALWAYS( cMask );
  685. *hSmallImageOpen = *hLargeImage = *hLargeImage = 0;
  686. return S_OK;
  687. }
  688. };
  689. #endif