home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / common / msdev98 / template / atl / snapin.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-16  |  14.8 KB  |  552 lines

  1. [!if=(FileExists, "FALSE")]
  2. #ifndef __[!UpperShortName]_H_
  3. #define __[!UpperShortName]_H_
  4. #include "resource.h"
  5. #include <atlsnap.h>
  6. [!else]
  7. [!AddIncludeFile(TargetFile,"resource.h")]
  8. [!AddIncludeFile(TargetFile, "<atlsnap.h>")]
  9. [!endif]
  10. [!crlf]
  11. [!if=(IExtendPropertySheet, "TRUE")]
  12. class [!ClassName]Page : public CSnapInPropertyPageImpl<[!ClassName]Page>
  13. {
  14. public :
  15.     [!ClassName]Page(long lNotifyHandle, bool bDeleteHandle = false, TCHAR* pTitle = NULL) : 
  16.         CSnapInPropertyPageImpl<[!ClassName]Page> (pTitle),
  17.         m_lNotifyHandle(lNotifyHandle),
  18.         m_bDeleteHandle(bDeleteHandle) // Should be true for only page.
  19.     {
  20.     }
  21. [!crlf]
  22.     ~[!ClassName]Page()
  23.     {
  24.         if (m_bDeleteHandle)
  25.             MMCFreeNotifyHandle(m_lNotifyHandle);
  26.     }
  27. [!crlf]
  28.     enum { IDD = [!IDD_PROPPAGE] };
  29. [!crlf]
  30. BEGIN_MSG_MAP([!ClassName]Page)
  31.     CHAIN_MSG_MAP(CSnapInPropertyPageImpl<[!ClassName]Page>)
  32. END_MSG_MAP()
  33. // Handler prototypes:
  34. //    LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  35. //    LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  36. //    LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
  37. [!crlf]
  38.     HRESULT PropertyChangeNotify(long param)
  39.     {
  40.         return MMCPropertyChangeNotify(m_lNotifyHandle, param);
  41.     }
  42. [!crlf]
  43. public:
  44.     long m_lNotifyHandle;
  45.     bool m_bDeleteHandle;
  46. };
  47. [!crlf]
  48. [!endif]
  49. [!if=(IComponentData, "TRUE")]
  50. class [!ClassName]Data : public CSnapInItemImpl<[!ClassName]Data>
  51. {
  52. public:
  53.     static const GUID* m_NODETYPE;
  54.     static const OLECHAR* m_SZNODETYPE;
  55.     static const OLECHAR* m_SZDISPLAY_NAME;
  56.     static const CLSID* m_SNAPIN_CLASSID;
  57. [!crlf]
  58.     CComPtr<IControlbar> m_spControlBar;
  59. [!crlf]
  60. [!if=(IExtendContextMenu, "TRUE")]
  61.     BEGIN_SNAPINCOMMAND_MAP([!ClassName]Data, FALSE)
  62.     END_SNAPINCOMMAND_MAP()
  63. [!crlf]
  64. [!else]
  65. [!if=(IExtendControlBar, "TRUE")]
  66.     BEGIN_SNAPINCOMMAND_MAP([!ClassName]Data, FALSE)
  67.     END_SNAPINCOMMAND_MAP()
  68. [!crlf]
  69. [!endif]
  70. [!endif]
  71. [!if=(IExtendContextMenu, "TRUE")]
  72.     SNAPINMENUID([!IDR_MENU])
  73. [!crlf]
  74. [!endif]
  75. [!if=(IExtendControlBar, "TRUE")]
  76.     BEGIN_SNAPINTOOLBARID_MAP([!ClassName]Data)
  77.         // Create toolbar resources with button dimensions 16x16 
  78.         // and add an entry to the MAP. You can add multiple toolbars
  79.         // SNAPINTOOLBARID_ENTRY(Toolbar ID)
  80.     END_SNAPINTOOLBARID_MAP()
  81. [!crlf]
  82. [!endif]
  83.     [!ClassName]Data()
  84.     {
  85.         // Image indexes may need to be modified depending on the images specific to 
  86.         // the snapin.
  87.  
  88.         memset(&m_scopeDataItem, 0, sizeof(SCOPEDATAITEM));
  89.         m_scopeDataItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM;
  90.         m_scopeDataItem.displayname = MMC_CALLBACK;
  91.         m_scopeDataItem.nImage = 0;         // May need modification
  92.         m_scopeDataItem.nOpenImage = 0;     // May need modification
  93.         m_scopeDataItem.lParam = (LPARAM) this;
  94.  
  95.         memset(&m_resultDataItem, 0, sizeof(RESULTDATAITEM));
  96.         m_resultDataItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  97.         m_resultDataItem.str = MMC_CALLBACK;
  98.         m_resultDataItem.nImage = 0;        // May need modification
  99.         m_resultDataItem.lParam = (LPARAM) this;
  100.     }
  101. [!crlf]
  102.     ~[!ClassName]Data()
  103.     {
  104.     }
  105. [!crlf]
  106. [!if=(IExtendPropertySheet, "TRUE")]
  107.     STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider,
  108.         long handle, 
  109.         IUnknown* pUnk,
  110.         DATA_OBJECT_TYPES type);
  111. [!crlf]
  112.     STDMETHOD(QueryPagesFor)(DATA_OBJECT_TYPES type)
  113.     {
  114.         if (type == CCT_SCOPE || type == CCT_RESULT)
  115.             return S_OK;
  116.         return S_FALSE;
  117.     }
  118. [!crlf]
  119. [!endif]
  120.  
  121.     STDMETHOD(GetScopePaneInfo)(SCOPEDATAITEM *pScopeDataItem);
  122. [!crlf]
  123.     STDMETHOD(GetResultPaneInfo)(RESULTDATAITEM *pResultDataItem);
  124. [!crlf]
  125.     STDMETHOD(Notify)( MMC_NOTIFY_TYPE event,
  126.         long arg,
  127.         long param,
  128.         IComponentData* pComponentData,
  129.         IComponent* pComponent,
  130.         DATA_OBJECT_TYPES type);
  131. [!crlf]
  132.     LPOLESTR GetResultPaneColInfo(int nCol);
  133. };
  134. [!endif]
  135. [!if=(EXTENSIONSNAPIN, "TRUE")]
  136. [!crlf]
  137. class [!ClassName]ExtData : public CSnapInItemImpl<[!ClassName]ExtData, TRUE>
  138. {
  139. public:
  140.     static const GUID* m_NODETYPE;
  141.     static const OLECHAR* m_SZNODETYPE;
  142.     static const OLECHAR* m_SZDISPLAY_NAME;
  143.     static const CLSID* m_SNAPIN_CLASSID;
  144. [!crlf]
  145. [!if=(IExtendContextMenu, "TRUE")]
  146.     BEGIN_SNAPINCOMMAND_MAP([!ClassName]ExtData, FALSE)
  147.     END_SNAPINCOMMAND_MAP()
  148. [!crlf]
  149. [!else]
  150. [!if=(IExtendControlBar, "TRUE")]
  151.     BEGIN_SNAPINCOMMAND_MAP([!ClassName]ExtData, FALSE)
  152.     END_SNAPINCOMMAND_MAP()
  153. [!crlf]
  154. [!endif]
  155. [!endif]
  156. [!if=(IExtendContextMenu, "TRUE")]
  157.     SNAPINMENUID([!IDR_MENU])
  158. [!crlf]
  159. [!endif]
  160. [!if=(IExtendControlBar, "TRUE")]
  161.     BEGIN_SNAPINTOOLBARID_MAP([!ClassName]ExtData)
  162.         // Create toolbar resources with button dimensions 16x16 
  163.         // and add an entry to the MAP. You can add multiple toolbars
  164.         // SNAPINTOOLBARID_ENTRY(Toolbar ID)
  165.     END_SNAPINTOOLBARID_MAP()
  166. [!crlf]
  167. [!endif]
  168.     [!ClassName]ExtData()
  169.     {
  170.         memset(&m_scopeDataItem, 0, sizeof(SCOPEDATAITEM));
  171.         memset(&m_resultDataItem, 0, sizeof(RESULTDATAITEM));
  172.     }
  173. [!crlf]
  174.     ~[!ClassName]ExtData()
  175.     {
  176.     }
  177. [!crlf]
  178. [!if=(IExtendPropertySheet, "TRUE")]
  179.     STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider,
  180.         long handle, 
  181.         IUnknown* pUnk,
  182.         DATA_OBJECT_TYPES type);
  183. [!crlf]
  184.     STDMETHOD(QueryPagesFor)(DATA_OBJECT_TYPES type)
  185.     {
  186.         if (type == CCT_SCOPE || type == CCT_RESULT)
  187.             return S_OK;
  188.         return S_FALSE;
  189.     }
  190. [!crlf]
  191. [!endif]
  192.     IDataObject* m_pDataObject;
  193.  
  194.     virtual void InitDataClass(IDataObject* pDataObject, CSnapInItem* pDefault)
  195.     {
  196.         m_pDataObject = pDataObject;
  197.         // The default code stores off the pointer to the Dataobject the class is wrapping
  198.         // at the time. 
  199.         // Alternatively you could convert the dataobject to the internal format
  200.         // it represents and store that information
  201.     }
  202. [!crlf]
  203.     CSnapInItem* GetExtNodeObject(IDataObject* pDataObject, CSnapInItem* pDefault)
  204.     {
  205.         // Modify to return a different CSnapInItem* pointer.
  206.  
  207.         return pDefault;
  208.     }
  209. [!crlf]
  210. };
  211. [!endif]
  212. [!if=(IComponent, "TRUE")]
  213. [!crlf]
  214. class [!ClassName];
  215. [!crlf]
  216. class [!ClassName]Component : public CComObjectRootEx<CComSingleThreadModel>,
  217.     public CSnapInObjectRoot<2, [!ClassName] >,
  218. [!if=(IExtendPropertySheet, "TRUE")]
  219.     public IExtendPropertySheetImpl<[!ClassName]Component>,
  220. [!endif]
  221. [!if=(IExtendContextMenu, "TRUE")]
  222.     public IExtendContextMenuImpl<[!ClassName]Component>,
  223. [!endif]
  224. [!if=(IExtendControlBar, "TRUE")]
  225.     public IExtendControlbarImpl<[!ClassName]Component>,
  226. [!endif]
  227. [!if=(PERSIST, "TRUE")]
  228. [!if=(IPersistStorage, "TRUE")]    public IPersistStorage,[!endif]
  229. [!if=(IPersistStream, "TRUE")]    public IPersistStream,[!endif]
  230. [!if=(IPersistStreamInit, "TRUE")]    public IPersistStreamInit,[!endif]
  231. [!endif]
  232.     public IComponentImpl<[!ClassName]Component>
  233. {
  234. public:
  235. BEGIN_COM_MAP([!ClassName]Component)
  236.     COM_INTERFACE_ENTRY(IComponent)
  237. [!if=(IExtendPropertySheet, "TRUE")]    COM_INTERFACE_ENTRY(IExtendPropertySheet)[!endif]
  238. [!if=(IExtendContextMenu, "TRUE")]    COM_INTERFACE_ENTRY(IExtendContextMenu)[!endif]
  239. [!if=(IExtendControlBar, "TRUE")]    COM_INTERFACE_ENTRY(IExtendControlbar)[!endif]
  240. [!if=(PERSIST, "TRUE")]
  241. [!if=(IPersistStorage, "TRUE")]    COM_INTERFACE_ENTRY(IPersistStorage)[!endif]
  242. [!if=(IPersistStream, "TRUE")]    COM_INTERFACE_ENTRY(IPersistStream)[!endif]
  243. [!if=(IPersistStreamInit, "TRUE")]    COM_INTERFACE_ENTRY(IPersistStreamInit)[!endif]
  244. [!endif]
  245. END_COM_MAP()
  246. [!crlf]
  247. public:
  248.     [!ClassName]Component()
  249.     {
  250.     }
  251. [!crlf]
  252.     STDMETHOD(Notify)(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, long arg, long param)
  253.     {
  254.         if (lpDataObject != NULL)
  255.             return IComponentImpl<[!ClassName]Component>::Notify(lpDataObject, event, arg, param);
  256.  
  257.         // TODO : Add code to handle notifications that set lpDataObject == NULL.
  258.         return E_NOTIMPL;
  259.     }
  260. [!crlf]
  261. [!if=(PERSIST, "TRUE")]
  262.     STDMETHOD(GetClassID)(CLSID *pClassID)
  263.     {
  264.         ATLTRACENOTIMPL(_T("[!ClassName]Component::GetClassID"));
  265.     }    
  266. [!crlf]
  267.     STDMETHOD(IsDirty)()
  268.     {
  269.         ATLTRACENOTIMPL(_T("[!ClassName]Component::IsDirty"));
  270.     }
  271. [!crlf]
  272. [!if=(IPersistStorage, "TRUE")]
  273.     STDMETHOD(InitNew)(IStorage *pStg)
  274.     {
  275.         ATLTRACE(_T("[!ClassName]Component::InitNew\n"));
  276.         return S_OK;
  277.     }
  278. [!crlf]
  279.     STDMETHOD(Load)(IStorage *pStg)
  280.     {
  281.         ATLTRACENOTIMPL(_T("[!ClassName]Component::Load"));
  282.     }
  283. [!crlf]
  284.     virtual HRESULT STDMETHODCALLTYPE Save(IStorage *pStgSave,
  285.         BOOL fSameAsLoad)
  286.     {
  287.         ATLTRACENOTIMPL(_T("[!ClassName]Component::Save"));
  288.     }
  289. [!crlf]
  290.     virtual HRESULT STDMETHODCALLTYPE SaveCompleted(IStorage *pStgNew)
  291.     {
  292.         ATLTRACENOTIMPL(_T("[!ClassName]Component::SaveCompleted"));
  293.     }
  294. [!crlf]
  295.     virtual HRESULT STDMETHODCALLTYPE HandsOffStorage()
  296.     {
  297.         ATLTRACENOTIMPL(_T("[!ClassName]Component::HandsOffStorage"));
  298.     }
  299. [!else]
  300.     STDMETHOD(Load)(IStream *pStm)
  301.     {
  302.         ATLTRACENOTIMPL(_T("[!ClassName]Component::Load"));
  303.     }
  304. [!crlf]
  305.     STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty)
  306.     {
  307.         ATLTRACENOTIMPL(_T("[!ClassName]Component::Save"));
  308.     }
  309. [!crlf]
  310.     STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize)
  311.     {
  312.         ATLTRACENOTIMPL(_T("[!ClassName]Component::GetSizeMax"));
  313.     }
  314. [!crlf]
  315. [!if=(IPersistStreamInit, "TRUE")]
  316.     STDMETHOD(InitNew)()
  317.     {
  318.         ATLTRACE(_T("[!ClassName]Component::InitNew\n"));
  319.         return S_OK;
  320.     }
  321. [!crlf]
  322.  
  323. [!endif]
  324. [!endif]
  325. [!endif]
  326. };
  327. [!crlf]
  328. [!endif]
  329.  
  330. class [!ClassName] : public CComObjectRootEx<CComSingleThreadModel>,
  331. public CSnapInObjectRoot<[!if=(IComponentData, "TRUE")]1[!else]0[!endif], [!ClassName]>,
  332. [!if=(IComponentData, "TRUE")]
  333.     public IComponentDataImpl<[!ClassName], [!ClassName]Component>,
  334. [!endif]
  335. [!if=(EXTENSIONSNAPIN, "TRUE")]
  336. [!if=(IExtendControlBar, "TRUE")]
  337.     public IExtendControlbarImpl<[!ClassName]>,
  338. [!endif]
  339. [!endif]
  340. [!if=(IExtendPropertySheet, "TRUE")]
  341.     public IExtendPropertySheetImpl<[!ClassName]>,
  342. [!endif]
  343. [!if=(IExtendContextMenu, "TRUE")]
  344.     public IExtendContextMenuImpl<[!ClassName]>,
  345. [!endif]
  346. [!if=(PERSIST, "TRUE")]
  347. [!if=(IPersistStorage, "TRUE")]    public IPersistStorage,[!endif]
  348. [!if=(IPersistStream, "TRUE")]    public IPersistStream,[!endif]
  349. [!if=(IPersistStreamInit, "TRUE")]    public IPersistStreamInit,[!endif]
  350. [!endif]
  351.     public CComCoClass<[!ClassName], &CLSID_[!CoClassName]>
  352. {
  353. public:
  354.     [!ClassName]()
  355.     {
  356. [!if=(IComponentData, "TRUE")]
  357.         m_pNode = new [!ClassName]Data;
  358.         _ASSERTE(m_pNode != NULL);
  359. [!endif]
  360.         m_pComponentData = this;
  361.     }
  362. [!if=(IComponentData, "TRUE")]
  363. [!crlf]
  364.     ~[!ClassName]()
  365.     {
  366.         delete m_pNode;
  367.         m_pNode = NULL;
  368.     }
  369.  
  370. [!crlf]
  371. [!endif]
  372. [!if=(EXTENSIONSNAPIN, "TRUE")]
  373. EXTENSION_SNAPIN_DATACLASS([!ClassName]ExtData)
  374. [!crlf]
  375. BEGIN_EXTENSION_SNAPIN_NODEINFO_MAP([!ClassName])
  376.     EXTENSION_SNAPIN_NODEINFO_ENTRY([!ClassName]ExtData)
  377. END_EXTENSION_SNAPIN_NODEINFO_MAP()
  378. [!crlf]
  379. [!endif]
  380. BEGIN_COM_MAP([!ClassName])
  381. [!if=(IComponentData, "TRUE")]      COM_INTERFACE_ENTRY(IComponentData)[!endif]
  382. [!if=(EXTENSIONSNAPIN, "TRUE")][!if=(IExtendControlBar, "TRUE")]    COM_INTERFACE_ENTRY(IExtendControlbar)[!endif][!endif]
  383. [!if=(IExtendPropertySheet, "TRUE")]    COM_INTERFACE_ENTRY(IExtendPropertySheet)[!endif]
  384. [!if=(IExtendContextMenu, "TRUE")]    COM_INTERFACE_ENTRY(IExtendContextMenu)[!endif]
  385. [!if=(PERSIST, "TRUE")]
  386. [!if=(IPersistStorage, "TRUE")]    COM_INTERFACE_ENTRY(IPersistStorage)[!endif]
  387. [!if=(IPersistStream, "TRUE")]    COM_INTERFACE_ENTRY(IPersistStream)[!endif]
  388. [!if=(IPersistStreamInit, "TRUE")]    COM_INTERFACE_ENTRY(IPersistStreamInit)[!endif]
  389. [!endif]
  390. END_COM_MAP()
  391. [!crlf]
  392. DECLARE_REGISTRY_RESOURCEID([!IDR_REGISTRYID])
  393. [!crlf]
  394. DECLARE_NOT_AGGREGATABLE([!ClassName])
  395. [!crlf]
  396. [!if=(PERSIST, "TRUE")]
  397.     STDMETHOD(GetClassID)(CLSID *pClassID)
  398.     {
  399.         ATLTRACENOTIMPL(_T("[!ClassName]::GetClassID"));
  400.     }    
  401. [!crlf]
  402.     STDMETHOD(IsDirty)()
  403.     {
  404.         ATLTRACENOTIMPL(_T("[!ClassName]::IsDirty"));
  405.     }
  406. [!crlf]
  407. [!if=(IPersistStorage, "TRUE")]
  408.     STDMETHOD(InitNew)(IStorage *pStg)
  409.     {
  410.         ATLTRACE(_T("[!ClassName]::InitNew\n"));
  411.         return S_OK;
  412.     }
  413. [!crlf]
  414.     STDMETHOD(Load)(IStorage *pStg)
  415.     {
  416.         ATLTRACENOTIMPL(_T("[!ClassName]::Load"));
  417.     }
  418. [!crlf]
  419.     virtual HRESULT STDMETHODCALLTYPE Save(IStorage *pStgSave,
  420.         BOOL fSameAsLoad)
  421.     {
  422.         ATLTRACENOTIMPL(_T("[!ClassName]::Save"));
  423.     }
  424. [!crlf]
  425.     virtual HRESULT STDMETHODCALLTYPE SaveCompleted(IStorage *pStgNew)
  426.     {
  427.         ATLTRACENOTIMPL(_T("[!ClassName]::SaveCompleted"));
  428.     }
  429. [!crlf]
  430.     virtual HRESULT STDMETHODCALLTYPE HandsOffStorage()
  431.     {
  432.         ATLTRACENOTIMPL(_T("[!ClassName]::HandsOffStorage"));
  433.     }
  434. [!crlf]
  435. [!else]
  436.     STDMETHOD(Load)(IStream *pStm)
  437.     {
  438.         ATLTRACENOTIMPL(_T("[!ClassName]::Load"));
  439.     }
  440. [!crlf]
  441.     STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty)
  442.     {
  443.         ATLTRACENOTIMPL(_T("[!ClassName]::Save"));
  444.     }
  445. [!crlf]
  446.     STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize)
  447.     {
  448.         ATLTRACENOTIMPL(_T("[!ClassName]::GetSizeMax"));
  449.     }
  450. [!crlf]
  451. [!if=(IPersistStreamInit, "TRUE")]
  452.     STDMETHOD(InitNew)()
  453.     {
  454.         ATLTRACE(_T("[!ClassName]::InitNew\n"));
  455.         return S_OK;
  456.     }
  457. [!crlf]
  458. [!endif]
  459. [!endif]
  460. [!endif]
  461. [!if=(IComponentData, "TRUE")]
  462.     STDMETHOD(Initialize)(LPUNKNOWN pUnknown);
  463. [!endif]
  464. [!crlf]
  465.     static void WINAPI ObjectMain(bool bStarting)
  466.     {
  467.         if (bStarting)
  468.             CSnapInItem::Init();
  469.     }
  470. };
  471. [!crlf]
  472.  
  473. [!if=(ISnapinAbout, "TRUE")]
  474. class ATL_NO_VTABLE [!ClassName]About : public ISnapinAbout,
  475.     public CComObjectRoot,
  476.     public CComCoClass< [!ClassName]About, &CLSID_[!CoClassName]About>
  477. {
  478. public:
  479.     DECLARE_REGISTRY([!ClassName]About, _T("[!CoClassName]About.1"), _T("[!CoClassName]About.1"), [!IDS_DESC], THREADFLAGS_BOTH);
  480. [!crlf]
  481.     BEGIN_COM_MAP([!ClassName]About)
  482.         COM_INTERFACE_ENTRY(ISnapinAbout)
  483.     END_COM_MAP()
  484. [!crlf]
  485.     STDMETHOD(GetSnapinDescription)(LPOLESTR *lpDescription)
  486.     {
  487.         USES_CONVERSION;
  488.         TCHAR szBuf[256];
  489.         if (::LoadString(_Module.GetResourceInstance(), [!IDS_DESC], szBuf, 256) == 0)
  490.             return E_FAIL;
  491. [!crlf]
  492.         *lpDescription = (LPOLESTR)CoTaskMemAlloc((lstrlen(szBuf) + 1) * sizeof(OLECHAR));
  493.         if (*lpDescription == NULL)
  494.             return E_OUTOFMEMORY;
  495. [!crlf]
  496.         ocscpy(*lpDescription, T2OLE(szBuf));
  497. [!crlf]
  498.         return S_OK;
  499.     }
  500. [!crlf]
  501.     STDMETHOD(GetProvider)(LPOLESTR *lpName)
  502.     {
  503.         USES_CONVERSION;
  504.         TCHAR szBuf[256];
  505.         if (::LoadString(_Module.GetResourceInstance(), [!IDS_PROVIDER], szBuf, 256) == 0)
  506.             return E_FAIL;
  507. [!crlf]
  508.         *lpName = (LPOLESTR)CoTaskMemAlloc((lstrlen(szBuf) + 1) * sizeof(OLECHAR));
  509.         if (*lpName == NULL)
  510.             return E_OUTOFMEMORY;
  511. [!crlf]
  512.         ocscpy(*lpName, T2OLE(szBuf));
  513. [!crlf]
  514.         return S_OK;
  515.     }
  516. [!crlf]
  517.     STDMETHOD(GetSnapinVersion)(LPOLESTR *lpVersion)
  518.     {
  519.         USES_CONVERSION;
  520.         TCHAR szBuf[256];
  521.         if (::LoadString(_Module.GetResourceInstance(), [!IDS_VERSION], szBuf, 256) == 0)
  522.             return E_FAIL;
  523. [!crlf]
  524.         *lpVersion = (LPOLESTR)CoTaskMemAlloc((lstrlen(szBuf) + 1) * sizeof(OLECHAR));
  525.         if (*lpVersion == NULL)
  526.             return E_OUTOFMEMORY;
  527. [!crlf]
  528.         ocscpy(*lpVersion, T2OLE(szBuf));
  529. [!crlf]
  530.         return S_OK;
  531.     }
  532. [!crlf]
  533.     STDMETHOD(GetSnapinImage)(HICON *hAppIcon)
  534.     {
  535.         *hAppIcon = NULL;
  536.         return S_OK;
  537.     }
  538. [!crlf]
  539.     STDMETHOD(GetStaticFolderImage)(HBITMAP *hSmallImage,
  540.         HBITMAP *hSmallImageOpen,
  541.         HBITMAP *hLargeImage,
  542.         COLORREF *cMask)
  543.     {
  544.         *hSmallImageOpen = *hLargeImage = *hLargeImage = 0;
  545.         return S_OK;
  546.     }
  547. };
  548. [!crlf]
  549. [!endif]
  550. [!if=(FileExists, "FALSE")]
  551. #endif
  552. [!endif]