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.

1964 lines
53 KiB

  1. /*--------------------------------------------------------------------------*
  2. *
  3. * Microsoft Windows
  4. * Copyright (C) Microsoft Corporation, 1999 - 1999
  5. *
  6. * File: fldrsnap.cpp
  7. *
  8. * Contents: Implementation file for built-in snapins that implement
  9. * the Folder, ActiveX Control, and Web Link nodes.
  10. * These replace earlier code that had special "built-in"
  11. * nodetypes.
  12. *
  13. * History: 23-Jul-98 vivekj Created
  14. *
  15. *--------------------------------------------------------------------------*/
  16. #include "stdafx.h"
  17. #include "tstring.h"
  18. #include "fldrsnap.h"
  19. #include "imageid.h"
  20. #include <comcat.h> // COM Component Categoories Manager
  21. #include "compcat.h"
  22. #include "guids.h"
  23. #include "regutil.h"
  24. #include "newnode.h"
  25. // These must now be the same - CMTNode::ScConvertLegacyNode depends on it.
  26. #define SZ_OCXSTREAM (L"ocx_streamorstorage")
  27. #define SZ_OCXSTORAGE (L"ocx_streamorstorage")
  28. /*+-------------------------------------------------------------------------*
  29. *
  30. * ScLoadAndAllocateString
  31. *
  32. * PURPOSE: Loads the string specified by the string ID and returns a string
  33. * whose storage has been allocated by CoTaskMemAlloc.
  34. *
  35. * PARAMETERS:
  36. * UINT ids :
  37. * LPOLESTR * lpstrOut :
  38. *
  39. * RETURNS:
  40. * SC
  41. *
  42. *+-------------------------------------------------------------------------*/
  43. SC
  44. ScLoadAndAllocateString(UINT ids, LPOLESTR *lpstrOut)
  45. {
  46. DECLARE_SC(sc, TEXT("ScLoadAndAllocateString"));
  47. sc = ScCheckPointers(lpstrOut);
  48. if(sc)
  49. return sc.ToHr();
  50. USES_CONVERSION;
  51. CStr str;
  52. str.LoadString(GetStringModule(), ids);
  53. *lpstrOut = (LPOLESTR) CoTaskMemAlloc( (str.GetLength() +1) *sizeof(OLECHAR) );
  54. if(*lpstrOut)
  55. wcscpy(*lpstrOut, T2CW(str));
  56. else
  57. sc = E_OUTOFMEMORY;
  58. return sc.ToHr();
  59. }
  60. //############################################################################
  61. //############################################################################
  62. //
  63. // Implementation of class CSnapinDescriptor
  64. //
  65. //############################################################################
  66. //############################################################################
  67. /*+-------------------------------------------------------------------------*
  68. *
  69. * CSnapinDescriptor::CSnapinDescriptor
  70. *
  71. * PURPOSE: Constructor
  72. *
  73. *+-------------------------------------------------------------------------*/
  74. CSnapinDescriptor::CSnapinDescriptor()
  75. : m_idsName(0), m_idsDescription(0), m_idiSnapinImage(0), m_idbSmallImage(0), m_idbSmallImageOpen(0),
  76. m_idbLargeImage(0), m_clsidSnapin(GUID_NULL), m_szClsidSnapin(TEXT("")),
  77. m_guidNodetype(GUID_NULL), m_szGuidNodetype(TEXT("")), m_szClassName(TEXT("")),
  78. m_szProgID(TEXT("")), m_szVersionIndependentProgID(TEXT("")), m_viewOptions(0)
  79. {
  80. }
  81. CSnapinDescriptor::CSnapinDescriptor(UINT idsName, UINT idsDescription, UINT idiSnapinImage,
  82. UINT idbSmallImage,UINT idbSmallImageOpen, UINT idbLargeImage,
  83. const CLSID &clsidSnapin, LPCTSTR szClsidSnapin,
  84. const GUID &guidNodetype, LPCTSTR szGuidNodetype,
  85. LPCTSTR szClassName, LPCTSTR szProgID,
  86. LPCTSTR szVersionIndependentProgID,
  87. long viewOptions)
  88. : m_idsName(idsName), m_idsDescription(idsDescription), m_idiSnapinImage(idiSnapinImage),
  89. m_idbSmallImage(idbSmallImage), m_idbSmallImageOpen(idbSmallImageOpen),
  90. m_idbLargeImage(idbLargeImage), m_clsidSnapin(clsidSnapin), m_szClsidSnapin(szClsidSnapin),
  91. m_guidNodetype(guidNodetype), m_szGuidNodetype(szGuidNodetype), m_szClassName(szClassName),
  92. m_szProgID(szProgID), m_szVersionIndependentProgID(szVersionIndependentProgID),
  93. m_viewOptions(viewOptions)
  94. {
  95. }
  96. /*+-------------------------------------------------------------------------*
  97. * ScFormatIndirectSnapInName
  98. *
  99. * Returns the name of the snap-in in the indirect form supported by
  100. * SHLoadRegUIString:
  101. *
  102. * @<dllname>,-<strId>
  103. *--------------------------------------------------------------------------*/
  104. SC ScFormatIndirectSnapInName (
  105. HINSTANCE hInst, /* I:module containing the resource */
  106. int idNameString, /* I:ID of name's string resource */
  107. CStr& strName) /* O:formatted indirect name string */
  108. {
  109. DECLARE_SC (sc, _T("ScFormatIndirectSnapInName"));
  110. /*
  111. * allocate a buffer for GetModuleFileName
  112. */
  113. const int cbBuffer = MAX_PATH;
  114. WTL::CString strStringModule;
  115. LPTSTR pBuffer = strStringModule.GetBuffer (cbBuffer);
  116. /*
  117. * if we couldn't allocate a buffer, return an error
  118. */
  119. if (pBuffer == NULL)
  120. return (sc = E_OUTOFMEMORY);
  121. /*
  122. * get the name of the module that provides strings
  123. */
  124. const DWORD cbCopied = GetModuleFileName (hInst, pBuffer, cbBuffer);
  125. strStringModule.ReleaseBuffer();
  126. /*
  127. * if GetModuleFileName failed, return its failure code
  128. */
  129. if (cbCopied == 0)
  130. {
  131. sc.FromLastError();
  132. /*
  133. * just in case GetModuleFileName didn't set the last error, make
  134. * sure the SC contains some kind of failure code
  135. */
  136. if (!sc.IsError())
  137. sc = E_FAIL;
  138. return (sc);
  139. }
  140. /*
  141. * if a path is present, SHLoadRegUIString won't search for the DLL
  142. * based on the current UI language; remove the path portion of the
  143. * module name so it will
  144. */
  145. int nLastPathSep = strStringModule.ReverseFind (_T('\\'));
  146. if (nLastPathSep != -1)
  147. strStringModule = strStringModule.Mid (nLastPathSep + 1);
  148. /*
  149. * format the name the way SHLoadRegUIString expects it
  150. */
  151. strStringModule.MakeLower();
  152. strName.Format (_T("@%s,-%d"), (LPCTSTR) strStringModule, idNameString);
  153. return (sc);
  154. }
  155. /*+-------------------------------------------------------------------------*
  156. * CSnapinDescriptor::GetRegisteredIndirectName
  157. *
  158. * Returns the name of the snap-in in the indirect form supported by
  159. * SHLoadRegUIString:
  160. *
  161. * @<dllname>,-<strId>
  162. *--------------------------------------------------------------------------*/
  163. void
  164. CSnapinDescriptor::GetRegisteredIndirectName(CStr &strIndirectName)
  165. {
  166. DECLARE_SC (sc, _T("CSnapinDescriptor::GetRegisteredIndirectName"));
  167. sc = ScFormatIndirectSnapInName (GetStringModule(), m_idsName, strIndirectName);
  168. if (sc)
  169. sc.TraceAndClear();
  170. }
  171. /*+-------------------------------------------------------------------------*
  172. * CSnapinDescriptor::GetRegisteredDefaultName
  173. *
  174. * Returns the name of the snap-in in the indirect form supported by
  175. * SHLoadRegUIString:
  176. *
  177. * @<dllname>,-<strId>
  178. *--------------------------------------------------------------------------*/
  179. void
  180. CSnapinDescriptor::GetRegisteredDefaultName(CStr &str)
  181. {
  182. str.LoadString (GetStringModule(), m_idsName);
  183. }
  184. /*+-------------------------------------------------------------------------*
  185. * CSnapinDescriptor::GetName
  186. *
  187. * Returns the human-readable name of the snap-in.
  188. *--------------------------------------------------------------------------*/
  189. void
  190. CSnapinDescriptor::GetName(CStr &str)
  191. {
  192. DECLARE_SC (sc, _T("CSnapinDescriptor::GetName"));
  193. /*
  194. * get the name from the registry
  195. */
  196. sc = ScGetSnapinNameFromRegistry (m_szClsidSnapin, str);
  197. if (sc)
  198. sc.TraceAndClear();
  199. }
  200. HBITMAP
  201. CSnapinDescriptor::GetSmallImage()
  202. {
  203. WTL::CBitmap bmp;
  204. bmp.LoadBitmap(MAKEINTRESOURCE(m_idbSmallImage));
  205. return (bmp.Detach());
  206. }
  207. HBITMAP
  208. CSnapinDescriptor::GetSmallImageOpen()
  209. {
  210. WTL::CBitmap bmp;
  211. bmp.LoadBitmap(MAKEINTRESOURCE(m_idbSmallImageOpen));
  212. return (bmp.Detach());
  213. }
  214. HBITMAP
  215. CSnapinDescriptor::GetLargeImage()
  216. {
  217. WTL::CBitmap bmp;
  218. bmp.LoadBitmap(MAKEINTRESOURCE(m_idbLargeImage));
  219. return (bmp.Detach());
  220. }
  221. HICON
  222. CSnapinDescriptor::GetSnapinImage()
  223. {
  224. return LoadIcon( _Module.GetModuleInstance(), MAKEINTRESOURCE(m_idiSnapinImage));
  225. }
  226. long
  227. CSnapinDescriptor::GetViewOptions()
  228. {
  229. return m_viewOptions;
  230. }
  231. //############################################################################
  232. //############################################################################
  233. //
  234. // Implementation of class CSnapinComponentDataImpl
  235. //
  236. //############################################################################
  237. //############################################################################
  238. /*+-------------------------------------------------------------------------*
  239. *
  240. * CSnapinComponentDataImpl::CSnapinComponentDataImpl
  241. *
  242. * PURPOSE: Constructor
  243. *
  244. *+-------------------------------------------------------------------------*/
  245. CSnapinComponentDataImpl::CSnapinComponentDataImpl()
  246. : m_bDirty(false)
  247. {
  248. }
  249. void
  250. CSnapinComponentDataImpl::SetName(LPCTSTR sz)
  251. {
  252. m_strName = sz;
  253. }
  254. /*+-------------------------------------------------------------------------*
  255. *
  256. * CSnapinComponentDataImpl::SetView
  257. *
  258. * PURPOSE: Sets the view.
  259. *
  260. * PARAMETERS:
  261. * LPCTSTR sz :
  262. *
  263. * RETURNS:
  264. * void
  265. *
  266. *+-------------------------------------------------------------------------*/
  267. void
  268. CSnapinComponentDataImpl::SetView(LPCTSTR sz)
  269. {
  270. m_strView = sz;
  271. }
  272. STDMETHODIMP
  273. CSnapinComponentDataImpl::Initialize(LPUNKNOWN pUnknown)
  274. {
  275. m_spConsole2 = pUnknown;
  276. m_spConsoleNameSpace2 = pUnknown;
  277. return S_OK;
  278. }
  279. /*+-------------------------------------------------------------------------*
  280. *
  281. * CSnapinComponentDataImpl::Notify
  282. *
  283. * PURPOSE: Notification handler for the IComponentData implementation.
  284. *
  285. * PARAMETERS:
  286. * LPDATAOBJECT lpDataObject : As per MMC docs.
  287. * MMC_NOTIFY_TYPE event :
  288. * LPARAM arg :
  289. * LPARAM param :
  290. *
  291. * RETURNS:
  292. * STDMETHODIMP
  293. *
  294. *+-------------------------------------------------------------------------*/
  295. STDMETHODIMP
  296. CSnapinComponentDataImpl::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event,
  297. LPARAM arg, LPARAM param)
  298. {
  299. USES_CONVERSION;
  300. switch(event)
  301. {
  302. case MMCN_RENAME: // the root node is being renamed
  303. m_strName = OLE2T((LPOLESTR)param);
  304. SetDirty();
  305. return S_OK;
  306. case MMCN_PRELOAD:
  307. return OnPreload((HSCOPEITEM) arg);
  308. }
  309. return S_FALSE;
  310. }
  311. /*+-------------------------------------------------------------------------*
  312. *
  313. * CSnapinComponentDataImpl::OnPreload
  314. *
  315. * PURPOSE: sets the icon of the root node (which is the only node.)
  316. *
  317. * PARAMETERS:
  318. * HSCOPEITEM scopeItem :
  319. *
  320. * RETURNS:
  321. * HRESULT
  322. *
  323. *+-------------------------------------------------------------------------*/
  324. HRESULT
  325. CSnapinComponentDataImpl::OnPreload(HSCOPEITEM scopeItem)
  326. {
  327. SCOPEDATAITEM item;
  328. ZeroMemory (&item, sizeof(SCOPEDATAITEM));
  329. item.mask = SDI_CHILDREN;
  330. item.ID = scopeItem;
  331. item.cChildren = 0; // make sure no "+" sign is displayed.
  332. m_spConsoleNameSpace2->SetItem (&item);
  333. return S_OK;
  334. }
  335. /*+-------------------------------------------------------------------------*
  336. *
  337. * CSnapinComponentDataImpl::Destroy
  338. *
  339. * PURPOSE: Gives up all references to MMC.
  340. *
  341. * RETURNS:
  342. * STDMETHODIMP
  343. *
  344. *+-------------------------------------------------------------------------*/
  345. STDMETHODIMP
  346. CSnapinComponentDataImpl::Destroy()
  347. {
  348. m_spConsole2 = NULL;
  349. m_spConsoleNameSpace2 = NULL;
  350. return S_OK;
  351. }
  352. /*+-------------------------------------------------------------------------*
  353. *
  354. * CSnapinComponentDataImpl::QueryDataObject
  355. *
  356. * PURPOSE: Returns a data object for the specified node.
  357. *
  358. * PARAMETERS:
  359. * MMC_COOKIE cookie : NULL for the root node.
  360. * DATA_OBJECT_TYPES type :
  361. * LPDATAOBJECT* ppDataObject :
  362. *
  363. * RETURNS:
  364. * STDMETHODIMP
  365. *
  366. *+-------------------------------------------------------------------------*/
  367. STDMETHODIMP
  368. CSnapinComponentDataImpl::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  369. LPDATAOBJECT* ppDataObject)
  370. {
  371. ASSERT(cookie == NULL);
  372. if(cookie != NULL)
  373. return E_UNEXPECTED;
  374. CComObject<CSnapinDataObject> * pDataObject;
  375. CComObject<CSnapinDataObject>::CreateInstance(&pDataObject);
  376. if(pDataObject == NULL)
  377. return E_UNEXPECTED;
  378. pDataObject->Initialize(this, type);
  379. return pDataObject->QueryInterface(IID_IDataObject, (void**)ppDataObject);
  380. }
  381. /*+-------------------------------------------------------------------------*
  382. *
  383. * CSnapinComponentDataImpl::GetDisplayInfo
  384. *
  385. * PURPOSE: Gets the display info for the root (the only) node.
  386. *
  387. * PARAMETERS:
  388. * SCOPEDATAITEM* pScopeDataItem : [IN/OUT]: The structure to fill in
  389. * based on the mask value.
  390. *
  391. * RETURNS:
  392. * STDMETHODIMP
  393. *
  394. *+-------------------------------------------------------------------------*/
  395. STDMETHODIMP
  396. CSnapinComponentDataImpl::GetDisplayInfo( SCOPEDATAITEM* pScopeDataItem)
  397. {
  398. SCOPEDATAITEM &sdi = *pScopeDataItem;
  399. DWORD mask = sdi.mask;
  400. if(mask & SDI_STR)
  401. {
  402. sdi.displayname = (LPOLESTR) GetName();
  403. }
  404. if(mask & SDI_IMAGE)
  405. {
  406. sdi.nImage = m_iImage;
  407. }
  408. if(mask & SDI_OPENIMAGE)
  409. {
  410. sdi.nImage = m_iOpenImage;
  411. }
  412. if(mask & SDI_STATE)
  413. {
  414. }
  415. if(mask & SDI_CHILDREN)
  416. {
  417. sdi.cChildren =0;
  418. }
  419. return S_OK;
  420. }
  421. /*+-------------------------------------------------------------------------*
  422. *
  423. * CSnapinComponentDataImpl::CompareObjects
  424. *
  425. * PURPOSE: Determines whether two data objects correspond to the same
  426. * underlying object.
  427. *
  428. * PARAMETERS:
  429. * LPDATAOBJECT lpDataObjectA :
  430. * LPDATAOBJECT lpDataObjectB :
  431. *
  432. * RETURNS:
  433. * STDMETHODIMP : S_OK if they correspond to the same object, else S_FALSE.
  434. *
  435. *+-------------------------------------------------------------------------*/
  436. STDMETHODIMP
  437. CSnapinComponentDataImpl::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  438. {
  439. return (lpDataObjectA == lpDataObjectB) ? S_OK : S_FALSE;
  440. }
  441. // IPersistStream
  442. /*+-------------------------------------------------------------------------*
  443. *
  444. * CSnapinComponentDataImpl::GetClassID
  445. *
  446. * PURPOSE:
  447. *
  448. * PARAMETERS:
  449. * CLSID * pClassID :
  450. *
  451. * RETURNS:
  452. * STDMETHODIMP
  453. *
  454. *+-------------------------------------------------------------------------*/
  455. STDMETHODIMP
  456. CSnapinComponentDataImpl::GetClassID(CLSID *pClassID)
  457. {
  458. return E_NOTIMPL;
  459. }
  460. /*+-------------------------------------------------------------------------*
  461. *
  462. * CSnapinComponentDataImpl::IsDirty
  463. *
  464. * PURPOSE:
  465. *
  466. * PARAMETERS:
  467. * voi d :
  468. *
  469. * RETURNS:
  470. * STDMETHODIMP
  471. *
  472. *+-------------------------------------------------------------------------*/
  473. STDMETHODIMP
  474. CSnapinComponentDataImpl::IsDirty(void)
  475. {
  476. TraceDirtyFlag(TEXT("CSnapinComponentDataImpl (MMC Built-in snapin)"), m_bDirty);
  477. return m_bDirty ? S_OK : S_FALSE;
  478. }
  479. /*+-------------------------------------------------------------------------*
  480. *
  481. * CSnapinComponentDataImpl::Load
  482. *
  483. * PURPOSE:
  484. *
  485. * PARAMETERS:
  486. * LPSTREAM pStm :
  487. *
  488. * RETURNS:
  489. * STDMETHODIMP
  490. *
  491. *+-------------------------------------------------------------------------*/
  492. STDMETHODIMP
  493. CSnapinComponentDataImpl::Load(LPSTREAM pStm)
  494. {
  495. return CSerialObject::Read(*pStm);
  496. }
  497. /*+-------------------------------------------------------------------------*
  498. *
  499. * CSnapinComponentDataImpl::Save
  500. *
  501. * PURPOSE:
  502. *
  503. * PARAMETERS:
  504. * LPSTREAM pStm :
  505. * BOOL fClearDirty :
  506. *
  507. * RETURNS:
  508. * STDMETHODIMP
  509. *
  510. *+-------------------------------------------------------------------------*/
  511. STDMETHODIMP
  512. CSnapinComponentDataImpl::Save(LPSTREAM pStm , BOOL fClearDirty)
  513. {
  514. HRESULT hr = CSerialObjectRW::Write(*pStm);
  515. if (SUCCEEDED(hr) && fClearDirty)
  516. SetDirty(FALSE);
  517. return hr;
  518. }
  519. /*+-------------------------------------------------------------------------*
  520. *
  521. * CSnapinComponentDataImpl::GetSizeMax
  522. *
  523. * PURPOSE:
  524. *
  525. * PARAMETERS:
  526. * ULARGE_INTEGER* pcbSize :
  527. *
  528. * RETURNS:
  529. * STDMETHODIMP
  530. *
  531. *+-------------------------------------------------------------------------*/
  532. STDMETHODIMP
  533. CSnapinComponentDataImpl::GetSizeMax(ULARGE_INTEGER* pcbSize )
  534. {
  535. return E_NOTIMPL;
  536. }
  537. /*+-------------------------------------------------------------------------*
  538. *
  539. * CSnapinComponentDataImpl::GetWatermarks
  540. *
  541. * PURPOSE: Sets the header for the wizard
  542. *
  543. * PARAMETERS:
  544. * LPDATAOBJECT lpIDataObject :
  545. * HBITMAP * lphWatermark :
  546. * HBITMAP * lphHeader :
  547. * HPALETTE * lphPalette :
  548. * BOOL* bStretch :
  549. *
  550. * RETURNS:
  551. * STDMETHODIMP
  552. *
  553. *+-------------------------------------------------------------------------*/
  554. STDMETHODIMP
  555. CSnapinComponentDataImpl::GetWatermarks(LPDATAOBJECT lpIDataObject, HBITMAP * lphWatermark, HBITMAP * lphHeader, HPALETTE * lphPalette, BOOL* bStretch)
  556. {
  557. DECLARE_SC(sc, TEXT("COCXSnapinData::ScGetWatermarks"));
  558. // validate inputs
  559. sc = ScCheckPointers(lpIDataObject, lphWatermark, lphHeader, lphPalette);
  560. if(sc)
  561. return sc.ToHr();
  562. // initialize outputs
  563. *lphWatermark = GetWatermark() ? ::LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(GetWatermark()))
  564. : NULL;
  565. // if there is a header, use it.
  566. *lphHeader = GetHeaderBitmap() ? ::LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(GetHeaderBitmap()))
  567. : NULL;
  568. *lphPalette = NULL;
  569. return sc.ToHr();
  570. }
  571. /*+-------------------------------------------------------------------------*
  572. *
  573. * CSnapinComponentDataImpl::QueryPagesFor
  574. *
  575. * PURPOSE:
  576. *
  577. * PARAMETERS:
  578. * LPDATAOBJECT lpDataObject :
  579. *
  580. * RETURNS:
  581. * STDMETHODIMP
  582. *
  583. *+-------------------------------------------------------------------------*/
  584. STDMETHODIMP
  585. CSnapinComponentDataImpl::QueryPagesFor(LPDATAOBJECT lpDataObject)
  586. {
  587. CSnapinDataObject *pDataObject = dynamic_cast<CSnapinDataObject *>(lpDataObject);
  588. if(pDataObject == NULL)
  589. return E_UNEXPECTED;
  590. if(pDataObject->GetType() != CCT_SNAPIN_MANAGER)
  591. return S_FALSE;
  592. return S_OK; // properties exist only in the snap-in manager.
  593. }
  594. /*+-------------------------------------------------------------------------*
  595. * CSnapinComponentDataImpl::GetHelpTopic
  596. *
  597. * Default implementation of ISnapinHelp::GetHelpTopic for built-in snap-
  598. * ins (folder, OCX, web page).
  599. *
  600. * We need to implement ISnapinHelp in the built-ins to avoid getting
  601. * "Help for <snap-in>" on the Help menu (bug 453700). They don't really
  602. * have help info, so we simply return S_FALSE so the help engine doesn't
  603. * complain.
  604. *--------------------------------------------------------------------------*/
  605. STDMETHODIMP CSnapinComponentDataImpl::GetHelpTopic (
  606. LPOLESTR* /*ppszCompiledHelpTopic*/)
  607. {
  608. return (S_FALSE); // no help topic
  609. }
  610. // CSerialObject methods
  611. /*+-------------------------------------------------------------------------*
  612. *
  613. * CSnapinComponentDataImpl::ReadSerialObject
  614. *
  615. * PURPOSE:
  616. *
  617. * PARAMETERS:
  618. * IStream & stm :
  619. * UINT nVersion :
  620. *
  621. * RETURNS:
  622. * HRESULT
  623. *
  624. *+-------------------------------------------------------------------------*/
  625. HRESULT
  626. CSnapinComponentDataImpl::ReadSerialObject (IStream &stm, UINT nVersion)
  627. {
  628. if(nVersion==1)
  629. {
  630. stm >> m_strName;
  631. stm >> m_strView;
  632. return S_OK;
  633. }
  634. else
  635. return S_FALSE; //unknown version, skip.
  636. }
  637. /*+-------------------------------------------------------------------------*
  638. *
  639. * CSnapinComponentDataImpl::WriteSerialObject
  640. *
  641. * PURPOSE:
  642. *
  643. * PARAMETERS:
  644. * IStream & stm :
  645. *
  646. * RETURNS:
  647. * HRESULT
  648. *
  649. *+-------------------------------------------------------------------------*/
  650. HRESULT
  651. CSnapinComponentDataImpl::WriteSerialObject(IStream &stm)
  652. {
  653. stm << m_strName;
  654. stm << m_strView;
  655. return S_OK;
  656. }
  657. //############################################################################
  658. //############################################################################
  659. //
  660. // Implementation of class CSnapinComponentImpl
  661. //
  662. //############################################################################
  663. //############################################################################
  664. /*+-------------------------------------------------------------------------*
  665. *
  666. * CSnapinComponentImpl::Init
  667. *
  668. * PURPOSE:
  669. *
  670. * PARAMETERS:
  671. * IComponentData * pComponentData :
  672. *
  673. * RETURNS:
  674. * void
  675. *
  676. *+-------------------------------------------------------------------------*/
  677. void
  678. CSnapinComponentImpl::Init(IComponentData *pComponentData)
  679. {
  680. m_spComponentData = pComponentData;
  681. }
  682. // IComponent
  683. /*+-------------------------------------------------------------------------*
  684. *
  685. * CSnapinComponentImpl::Initialize
  686. *
  687. * PURPOSE:
  688. *
  689. * PARAMETERS:
  690. * LPCONSOLE lpConsole :
  691. *
  692. * RETURNS:
  693. * STDMETHODIMP
  694. *
  695. *+-------------------------------------------------------------------------*/
  696. STDMETHODIMP
  697. CSnapinComponentImpl::Initialize(LPCONSOLE lpConsole)
  698. {
  699. m_spConsole2 = lpConsole;
  700. return S_OK;
  701. }
  702. /*+-------------------------------------------------------------------------*
  703. *
  704. * CSnapinComponentImpl::Notify
  705. *
  706. * PURPOSE:
  707. *
  708. * PARAMETERS:
  709. * LPDATAOBJECT lpDataObject :
  710. * MMC_NOTIFY_TYPE event :
  711. * LPARAM arg :
  712. * LPARAM param :
  713. *
  714. * RETURNS:
  715. * STDMETHODIMP
  716. *
  717. *+-------------------------------------------------------------------------*/
  718. STDMETHODIMP
  719. CSnapinComponentImpl::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event,
  720. LPARAM arg, LPARAM param)
  721. {
  722. switch(event)
  723. {
  724. case MMCN_SELECT:
  725. {
  726. BOOL bScope = (BOOL) LOWORD(arg);
  727. BOOL bSelect = (BOOL) HIWORD(arg);
  728. SC sc = ScOnSelect(bScope, bSelect);
  729. if(sc)
  730. return sc.ToHr();
  731. }
  732. return S_OK;
  733. break;
  734. default:
  735. break;
  736. }
  737. return S_FALSE;
  738. }
  739. /*+-------------------------------------------------------------------------*
  740. *
  741. * CSnapinComponentImpl::ScOnSelect
  742. *
  743. * PURPOSE:
  744. *
  745. * PARAMETERS:
  746. * BOOL bScope :
  747. * BOOL bSelect :
  748. *
  749. * RETURNS:
  750. * SC
  751. *
  752. *+-------------------------------------------------------------------------*/
  753. SC
  754. CSnapinComponentImpl::ScOnSelect(BOOL bScope, BOOL bSelect)
  755. {
  756. DECLARE_SC(sc, TEXT("CSnapinComponentImpl::ScOnSelect"));
  757. IConsoleVerbPtr spConsoleVerb;
  758. sc = m_spConsole2->QueryConsoleVerb(&spConsoleVerb);
  759. if(sc)
  760. return sc;
  761. sc = spConsoleVerb->SetVerbState(MMC_VERB_RENAME, ENABLED, (bSelect && bScope));
  762. if(sc)
  763. return sc;
  764. return sc;
  765. }
  766. /*+-------------------------------------------------------------------------*
  767. *
  768. * CSnapinComponentImpl::Destroy
  769. *
  770. * PURPOSE:
  771. *
  772. * PARAMETERS:
  773. * MMC_COOKIE cookie :
  774. *
  775. * RETURNS:
  776. * STDMETHODIMP
  777. *
  778. *+-------------------------------------------------------------------------*/
  779. STDMETHODIMP
  780. CSnapinComponentImpl::Destroy(MMC_COOKIE cookie)
  781. {
  782. m_spConsole2 = NULL;
  783. m_spComponentData = NULL;
  784. return S_OK;
  785. }
  786. /*+-------------------------------------------------------------------------*
  787. *
  788. * CSnapinComponentImpl::QueryDataObject
  789. *
  790. * PURPOSE:
  791. *
  792. * PARAMETERS:
  793. * MMC_COOKIE cookie :
  794. * DATA_OBJECT_TYPES type :
  795. * LPDATAOBJECT* ppDataObject :
  796. *
  797. * RETURNS:
  798. * STDMETHODIMP
  799. *
  800. *+-------------------------------------------------------------------------*/
  801. STDMETHODIMP
  802. CSnapinComponentImpl::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  803. LPDATAOBJECT* ppDataObject)
  804. {
  805. return E_NOTIMPL;
  806. }
  807. /*+-------------------------------------------------------------------------*
  808. *
  809. * CSnapinComponentImpl::GetComponentData
  810. *
  811. * PURPOSE:
  812. *
  813. * RETURNS:
  814. * CSnapinComponentDataImpl *
  815. *
  816. *+-------------------------------------------------------------------------*/
  817. CSnapinComponentDataImpl *
  818. CSnapinComponentImpl::GetComponentData()
  819. {
  820. CSnapinComponentDataImpl *pCD = dynamic_cast<CSnapinComponentDataImpl *>(m_spComponentData.GetInterfacePtr());
  821. ASSERT(pCD != NULL);
  822. return pCD;
  823. }
  824. /*+-------------------------------------------------------------------------*
  825. *
  826. * CSnapinComponentImpl::GetResultViewType
  827. *
  828. * PURPOSE:
  829. *
  830. * PARAMETERS:
  831. * MMC_COOKIE cookie :
  832. * LPOLESTR* ppViewType :
  833. * long* pViewOptions : Set to MMC_VIEW_OPTIONS_NOLISTVIEWS for the HTML and OCX snapins,
  834. * 0 for the folder snapin.
  835. *
  836. * RETURNS:
  837. * STDMETHODIMP
  838. *
  839. *+-------------------------------------------------------------------------*/
  840. STDMETHODIMP
  841. CSnapinComponentImpl::GetResultViewType(MMC_COOKIE cookie, LPOLESTR* ppViewType,
  842. long* pViewOptions)
  843. {
  844. // check parameters
  845. if(!ppViewType || !pViewOptions)
  846. return E_UNEXPECTED;
  847. if(!GetComponentData())
  848. return E_UNEXPECTED;
  849. USES_CONVERSION;
  850. *ppViewType = (LPOLESTR)CoTaskMemAlloc( (_tcslen(GetComponentData()->GetView())+1) * sizeof(OLECHAR) );
  851. *pViewOptions = GetComponentData()->GetDescriptor().GetViewOptions();
  852. wcscpy(*ppViewType, T2OLE((LPTSTR)GetComponentData()->GetView()));
  853. return S_OK;
  854. }
  855. /*+-------------------------------------------------------------------------*
  856. *
  857. * CSnapinComponentImpl::GetDisplayInfo
  858. *
  859. * PURPOSE:
  860. *
  861. * PARAMETERS:
  862. * RESULTDATAITEM* pResultDataItem :
  863. *
  864. * RETURNS:
  865. * STDMETHODIMP
  866. *
  867. *+-------------------------------------------------------------------------*/
  868. STDMETHODIMP
  869. CSnapinComponentImpl::GetDisplayInfo( RESULTDATAITEM* pResultDataItem)
  870. {
  871. RESULTDATAITEM &rdi = *pResultDataItem;
  872. DWORD mask = rdi.mask;
  873. if(mask & RDI_STR)
  874. {
  875. rdi.str = (LPOLESTR) GetComponentData()->GetName();
  876. }
  877. if(mask & RDI_IMAGE)
  878. {
  879. rdi.nImage = GetComponentData()->m_iImage;
  880. }
  881. return S_OK;
  882. }
  883. /*+-------------------------------------------------------------------------*
  884. *
  885. * CSnapinComponentImpl::CompareObjects
  886. *
  887. * PURPOSE:
  888. *
  889. * PARAMETERS:
  890. * LPDATAOBJECT lpDataObjectA :
  891. * LPDATAOBJECT lpDataObjectB :
  892. *
  893. * RETURNS:
  894. * STDMETHODIMP
  895. *
  896. *+-------------------------------------------------------------------------*/
  897. STDMETHODIMP
  898. CSnapinComponentImpl::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  899. {
  900. return E_NOTIMPL;
  901. }
  902. //############################################################################
  903. //############################################################################
  904. //
  905. // Implementation of class CSnapinDataObject
  906. //
  907. //############################################################################
  908. //############################################################################
  909. // Clipboard formats that are required by the console
  910. UINT CSnapinDataObject::s_cfNodeType;
  911. UINT CSnapinDataObject::s_cfNodeTypeString;
  912. UINT CSnapinDataObject::s_cfDisplayName;
  913. UINT CSnapinDataObject::s_cfCoClass;
  914. UINT CSnapinDataObject::s_cfSnapinPreloads;
  915. /*+-------------------------------------------------------------------------*
  916. *
  917. * CSnapinDataObject::RegisterClipboardFormats
  918. *
  919. * PURPOSE:
  920. *
  921. * RETURNS:
  922. * void
  923. *
  924. *+-------------------------------------------------------------------------*/
  925. void
  926. CSnapinDataObject::RegisterClipboardFormats()
  927. {
  928. static bool bRegistered = false;
  929. if(!bRegistered)
  930. {
  931. USES_CONVERSION;
  932. CSnapinDataObject::s_cfNodeType = RegisterClipboardFormat(OLE2T(CCF_NODETYPE));
  933. CSnapinDataObject::s_cfNodeTypeString = RegisterClipboardFormat(OLE2T(CCF_SZNODETYPE));
  934. CSnapinDataObject::s_cfDisplayName = RegisterClipboardFormat(OLE2T(CCF_DISPLAY_NAME));
  935. CSnapinDataObject::s_cfCoClass = RegisterClipboardFormat(OLE2T(CCF_SNAPIN_CLASSID));
  936. CSnapinDataObject::s_cfSnapinPreloads = RegisterClipboardFormat(OLE2T(CCF_SNAPIN_PRELOADS));
  937. bRegistered = true;
  938. }
  939. }
  940. CSnapinDataObject::CSnapinDataObject() : m_bInitialized(false)
  941. {
  942. }
  943. /*+-------------------------------------------------------------------------*
  944. *
  945. * CSnapinDataObject::GetDataHere
  946. *
  947. * PURPOSE:
  948. *
  949. * PARAMETERS:
  950. * FORMATETC * pformatetc :
  951. * STGMEDIUM * pmedium :
  952. *
  953. * RETURNS:
  954. * STDMETHODIMP
  955. *
  956. *+-------------------------------------------------------------------------*/
  957. STDMETHODIMP
  958. CSnapinDataObject::GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium)
  959. {
  960. DECLARE_SC(sc, TEXT("CSnapinDataObject::GetDataHere"));
  961. // validate inputs
  962. sc = ScCheckPointers(pformatetc, pmedium);
  963. if(sc)
  964. return sc.ToHr();
  965. USES_CONVERSION;
  966. RegisterClipboardFormats();
  967. // Based on the CLIPFORMAT write data to the stream
  968. const CLIPFORMAT cf = pformatetc->cfFormat;
  969. // ensure the medium is an HGLOBAL
  970. if(pformatetc->tymed != TYMED_HGLOBAL)
  971. return (sc = DV_E_TYMED).ToHr();
  972. IStreamPtr spStream;
  973. HGLOBAL hGlobal = pmedium->hGlobal;
  974. pmedium->pUnkForRelease = NULL; // by OLE spec
  975. sc = CreateStreamOnHGlobal( hGlobal, FALSE, &spStream );
  976. if(sc)
  977. return sc.ToHr();
  978. CSnapinComponentDataImpl *pComponentDataImpl =
  979. dynamic_cast<CSnapinComponentDataImpl *>(m_spComponentData.GetInterfacePtr());
  980. ASSERT(pComponentDataImpl != NULL);
  981. if (cf == s_cfNodeType)
  982. {
  983. spStream<<pComponentDataImpl->GetDescriptor().m_guidNodetype;
  984. }
  985. else if (cf == s_cfCoClass)
  986. {
  987. spStream<<pComponentDataImpl->GetDescriptor().m_clsidSnapin;
  988. }
  989. else if(cf == s_cfNodeTypeString)
  990. {
  991. WriteString(spStream, T2OLE((LPTSTR)pComponentDataImpl->GetDescriptor().m_szGuidNodetype));
  992. }
  993. else if (cf == s_cfDisplayName)
  994. {
  995. WriteString(spStream, T2OLE((LPTSTR)pComponentDataImpl->GetName()));
  996. }
  997. else if (cf == s_cfSnapinPreloads)
  998. {
  999. BOOL bPreload = true;
  1000. spStream->Write ((void *)&bPreload, sizeof(BOOL), NULL);
  1001. }
  1002. else
  1003. {
  1004. return (sc = DV_E_CLIPFORMAT).ToHr(); // invalid format.
  1005. }
  1006. return sc.ToHr();
  1007. }
  1008. /*+-------------------------------------------------------------------------*
  1009. *
  1010. * CSnapinDataObject::WriteString
  1011. *
  1012. * PURPOSE:
  1013. *
  1014. * PARAMETERS:
  1015. * IStream * pStream :
  1016. * LPCOLESTR sz :
  1017. *
  1018. * RETURNS:
  1019. * HRESULT
  1020. *
  1021. *+-------------------------------------------------------------------------*/
  1022. HRESULT
  1023. CSnapinDataObject::WriteString(IStream *pStream, LPCOLESTR sz)
  1024. {
  1025. HRESULT hr = S_OK;
  1026. ASSERT(pStream != NULL);
  1027. if(pStream == NULL)
  1028. {
  1029. //TraceError(TEXT("CSnapinDataObject::WriteString"));
  1030. return E_UNEXPECTED;
  1031. }
  1032. UINT cbToWrite = wcslen(sz)*sizeof(WCHAR);
  1033. ULONG cbActuallyWritten=0;
  1034. hr = pStream->Write (sz, cbToWrite, &cbActuallyWritten);
  1035. ASSERT(cbToWrite==cbActuallyWritten);
  1036. return hr;
  1037. }
  1038. /*+-------------------------------------------------------------------------*
  1039. *
  1040. * CSnapinDataObject::Initialize
  1041. *
  1042. * PURPOSE:
  1043. *
  1044. * PARAMETERS:
  1045. * IComponentData * pComponentData :
  1046. * DATA_OBJECT_TYPES type :
  1047. *
  1048. * RETURNS:
  1049. * void
  1050. *
  1051. *+-------------------------------------------------------------------------*/
  1052. void
  1053. CSnapinDataObject::Initialize(IComponentData *pComponentData, DATA_OBJECT_TYPES type)
  1054. {
  1055. ASSERT(pComponentData != NULL);
  1056. m_spComponentData = pComponentData;
  1057. m_type = type;
  1058. m_bInitialized = true;
  1059. }
  1060. //############################################################################
  1061. //############################################################################
  1062. //
  1063. // Implementation of class CFolderSnapinData
  1064. //
  1065. //############################################################################
  1066. //############################################################################
  1067. STDMETHODIMP
  1068. CFolderSnapinData::CreateComponent(LPCOMPONENT* ppComponent)
  1069. {
  1070. typedef CComObject<CFolderSnapinComponent> CComponent;
  1071. CComponent * pComponent = NULL;
  1072. CComObject<CFolderSnapinComponent>::CreateInstance(&pComponent);
  1073. ASSERT(pComponent != NULL);
  1074. if(pComponent == NULL)
  1075. {
  1076. //TraceError(TEXT("CFolderSnapinData::CreateComponent"));
  1077. return E_UNEXPECTED;
  1078. }
  1079. pComponent->Init(this);
  1080. return pComponent->QueryInterface(IID_IComponent, (void **)ppComponent); // does the Addref.
  1081. }
  1082. CFolderSnapinData::CFolderSnapinData()
  1083. {
  1084. m_iImage = eStockImage_Folder;
  1085. m_iOpenImage = eStockImage_OpenFolder;
  1086. }
  1087. const CLSID CLSID_FolderSnapin = {0xC96401CC, 0x0E17,0x11D3, {0x88,0x5B,0x00,0xC0,0x4F,0x72,0xC7,0x17}};
  1088. static const GUID GUID_FolderSnapinNodetype = {0xc96401ce, 0xe17, 0x11d3, { 0x88, 0x5b, 0x0, 0xc0, 0x4f, 0x72, 0xc7, 0x17 } };
  1089. static LPCTSTR szClsid_FolderSnapin = TEXT("{C96401CC-0E17-11D3-885B-00C04F72C717}");
  1090. static LPCTSTR szGuidFolderSnapinNodetype = TEXT("{C96401CE-0E17-11D3-885B-00C04F72C717}");
  1091. CSnapinDescriptor &
  1092. CFolderSnapinData::GetSnapinDescriptor()
  1093. {
  1094. static CSnapinDescriptor snapinDescription(IDS_FOLDER,
  1095. IDS_FOLDERSNAPIN_DESC, IDI_FOLDER, IDB_FOLDER_16, IDB_FOLDEROPEN_16, IDB_FOLDER_32,
  1096. CLSID_FolderSnapin, szClsid_FolderSnapin, GUID_FolderSnapinNodetype,
  1097. szGuidFolderSnapinNodetype, TEXT("Folder"), TEXT("Snapins.FolderSnapin"),
  1098. TEXT("Snapins.FolderSnapin.1"), 0 /*viewOptions*/ );
  1099. return snapinDescription;
  1100. }
  1101. // IExtendPropertySheet2
  1102. STDMETHODIMP
  1103. CFolderSnapinData::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, LPDATAOBJECT lpIDataObject)
  1104. {
  1105. return S_FALSE;
  1106. }
  1107. //############################################################################
  1108. //############################################################################
  1109. //
  1110. // Implementation of class CHTMLSnapinData
  1111. //
  1112. //############################################################################
  1113. //############################################################################
  1114. STDMETHODIMP
  1115. CHTMLSnapinData::CreateComponent(LPCOMPONENT* ppComponent)
  1116. {
  1117. typedef CComObject<CHTMLSnapinComponent> CComponent;
  1118. CComponent * pComponent = NULL;
  1119. CComObject<CHTMLSnapinComponent>::CreateInstance(&pComponent);
  1120. ASSERT(pComponent != NULL);
  1121. if(pComponent == NULL)
  1122. {
  1123. //TraceError(TEXT("CHTMLSnapinData::CreateComponent"));
  1124. return E_UNEXPECTED;
  1125. }
  1126. pComponent->Init(this);
  1127. return pComponent->QueryInterface(IID_IComponent, (void **)ppComponent); // does the Addref.
  1128. }
  1129. CHTMLSnapinData::CHTMLSnapinData()
  1130. {
  1131. m_pHtmlPage1 = NULL;
  1132. m_pHtmlPage2 = NULL;
  1133. m_iImage = eStockImage_HTML;
  1134. m_iOpenImage = eStockImage_HTML;
  1135. }
  1136. CHTMLSnapinData::~CHTMLSnapinData()
  1137. {
  1138. }
  1139. STDMETHODIMP
  1140. CHTMLSnapinData::Destroy()
  1141. {
  1142. if(m_pHtmlPage1 != NULL)
  1143. {
  1144. delete m_pHtmlPage1;
  1145. m_pHtmlPage1 = NULL;
  1146. }
  1147. if(m_pHtmlPage2 != NULL)
  1148. {
  1149. delete m_pHtmlPage2;
  1150. m_pHtmlPage2 = NULL;
  1151. }
  1152. return BC::Destroy();
  1153. }
  1154. const CLSID CLSID_HTMLSnapin = {0xC96401D1, 0x0E17,0x11D3, {0x88,0x5B,0x00,0xC0,0x4F,0x72,0xC7,0x17}};
  1155. static const GUID GUID_HTMLSnapinNodetype = {0xc96401d2, 0xe17, 0x11d3, { 0x88, 0x5b, 0x0, 0xc0, 0x4f, 0x72, 0xc7, 0x17 } };
  1156. static LPCTSTR szClsid_HTMLSnapin = TEXT("{C96401D1-0E17-11D3-885B-00C04F72C717}");
  1157. static LPCTSTR szGuidHTMLSnapinNodetype = TEXT("{C96401D2-0E17-11D3-885B-00C04F72C717}");
  1158. CSnapinDescriptor &
  1159. CHTMLSnapinData::GetSnapinDescriptor()
  1160. {
  1161. static CSnapinDescriptor snapinDescription(IDS_HTML,
  1162. IDS_HTMLSNAPIN_DESC, IDI_HTML, IDB_HTML_16, IDB_HTML_16, IDB_HTML_32,
  1163. CLSID_HTMLSnapin, szClsid_HTMLSnapin, GUID_HTMLSnapinNodetype,
  1164. szGuidHTMLSnapinNodetype, TEXT("HTML"), TEXT("Snapins.HTMLSnapin"),
  1165. TEXT("Snapins.HTMLSnapin.1"), MMC_VIEW_OPTIONS_NOLISTVIEWS /*viewOptions*/ );
  1166. return snapinDescription;
  1167. }
  1168. // IExtendPropertySheet2
  1169. /*+-------------------------------------------------------------------------*
  1170. *
  1171. * CHTMLSnapinData::CreatePropertyPages
  1172. *
  1173. * PURPOSE:
  1174. *
  1175. * PARAMETERS:
  1176. * LPPROPERTYSHEETCALLBACK lpProvider :
  1177. * LONG_PTR handle :
  1178. * LPDATAOBJECT lpIDataObject :
  1179. *
  1180. * RETURNS:
  1181. * STDMETHODIMP
  1182. *
  1183. *+-------------------------------------------------------------------------*/
  1184. STDMETHODIMP
  1185. CHTMLSnapinData::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, LPDATAOBJECT lpIDataObject)
  1186. {
  1187. HPROPSHEETPAGE hPage;
  1188. ASSERT(lpProvider != NULL);
  1189. if(lpProvider == NULL)
  1190. {
  1191. //TraceError(TEXT("CHTMLSnapinData::CreatePropertyPages"));
  1192. return E_UNEXPECTED;
  1193. }
  1194. ASSERT(m_pHtmlPage1 == NULL);
  1195. ASSERT(m_pHtmlPage2 == NULL);
  1196. // create property pages
  1197. m_pHtmlPage1 = new CHTMLPage1;
  1198. m_pHtmlPage2 = new CHTMLPage2;
  1199. // pass in pointer to data structure
  1200. m_pHtmlPage1->Initialize(this);
  1201. m_pHtmlPage2->Initialize(this);
  1202. // Add Pages to property sheet
  1203. hPage=CreatePropertySheetPage(&m_pHtmlPage1->m_psp);
  1204. lpProvider->AddPage(hPage);
  1205. hPage=CreatePropertySheetPage(&m_pHtmlPage2->m_psp);
  1206. lpProvider->AddPage(hPage);
  1207. return S_OK;
  1208. }
  1209. //############################################################################
  1210. //############################################################################
  1211. //
  1212. // Implementation of class CHTMLSnapinComponent
  1213. //
  1214. //############################################################################
  1215. //############################################################################
  1216. /*+-------------------------------------------------------------------------*
  1217. *
  1218. * CHTMLSnapinComponent::ScOnSelect
  1219. *
  1220. * PURPOSE: Handles the MMCN_SELECT notification. Enables the Refresh verb,
  1221. * which uses the default MMC handler to refresh the page.
  1222. *
  1223. * PARAMETERS:
  1224. * BOOL bScope :
  1225. * BOOL bSelect :
  1226. *
  1227. * RETURNS:
  1228. * SC
  1229. *
  1230. *+-------------------------------------------------------------------------*/
  1231. SC
  1232. CHTMLSnapinComponent::ScOnSelect(BOOL bScope, BOOL bSelect)
  1233. {
  1234. DECLARE_SC(sc, TEXT("CHTMLSnapinComponent::ScOnSelect"));
  1235. // call the base class method
  1236. sc = BC::ScOnSelect(bScope, bSelect);
  1237. if(sc)
  1238. return sc;
  1239. IConsoleVerbPtr spConsoleVerb;
  1240. sc = ScCheckPointers(m_spConsole2, E_UNEXPECTED);
  1241. if(sc)
  1242. return sc;
  1243. sc = m_spConsole2->QueryConsoleVerb(&spConsoleVerb);
  1244. if(sc)
  1245. return sc;
  1246. sc = ScCheckPointers(spConsoleVerb, E_UNEXPECTED);
  1247. if(sc)
  1248. return sc;
  1249. // enable the Refresh verb - the default MMC handler is adequate to refresh the page.
  1250. sc = spConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, (bSelect && bScope));
  1251. if(sc)
  1252. return sc;
  1253. //NOTE: (vivekj): I'm intentionally not setting the HIDDEN state to false here, because
  1254. // we have an explicit test in our verb code for MMC1.0 snapins that wrote code like this,
  1255. // and this provides a useful compatibility test.
  1256. return sc;
  1257. }
  1258. /*+-------------------------------------------------------------------------*
  1259. *
  1260. * CHTMLSnapinComponent::GetResultViewType
  1261. *
  1262. * PURPOSE: Performs parameter substitution on the URL for the environment variables
  1263. * %windir% and %systemroot% (only) and returns the expanded URL.
  1264. *
  1265. * NOTE: We don't expand ALL variables using ExpandEnvironmentString. Doing so could
  1266. * break compatibility with URL's that have %var% but DON'T want to be
  1267. * expanded.
  1268. *
  1269. * PARAMETERS:
  1270. * MMC_COOKIE cookie :
  1271. * LPOLESTR* ppViewType :
  1272. * long* pViewOptions :
  1273. *
  1274. * RETURNS:
  1275. * STDMETHODIMP
  1276. *
  1277. *+-------------------------------------------------------------------------*/
  1278. STDMETHODIMP
  1279. CHTMLSnapinComponent::GetResultViewType(MMC_COOKIE cookie, LPOLESTR* ppViewType, long* pViewOptions)
  1280. {
  1281. DECLARE_SC(sc, TEXT("CHTMLSnapinComponent::GetResultViewType"));
  1282. // check parameters
  1283. if(!ppViewType || !pViewOptions)
  1284. return (sc = E_UNEXPECTED).ToHr();
  1285. if(!GetComponentData())
  1286. return (sc = E_UNEXPECTED).ToHr();
  1287. // add support for expanding the environment variables %WINDIR% and %SYSTEMROOT% to maintain compatibility with MMC1.2
  1288. CStr strTarget = GetComponentData()->GetView();
  1289. CStr strRet = strTarget; // the return value
  1290. CStr strTemp = strTarget; // both initialized to the same value.
  1291. strTemp.MakeLower(); // NOTE: this lowercase conversion is used only for comparison. The original case is preserved in the output.
  1292. // Find out if %windir% or %systemroot% is in the target string
  1293. int nWndDir = strTemp.Find(MMC_WINDIR_VARIABLE_PERC);
  1294. int nSysDir = strTemp.Find(MMC_SYSTEMROOT_VARIABLE_PERC);
  1295. if (nWndDir != -1 || nSysDir != -1)
  1296. {
  1297. const UINT BUFFERLEN = 4096;
  1298. // Get start pos and length of replacement string
  1299. int nStpos = (nWndDir != -1) ? nWndDir : nSysDir;
  1300. int nLen = (nWndDir != -1) ? _tcslen(MMC_WINDIR_VARIABLE_PERC) : _tcslen(MMC_SYSTEMROOT_VARIABLE_PERC);
  1301. // Setup temp variable to hold BUFFERLEN chars
  1302. CStr strRoot;
  1303. LPTSTR lpsz = strRoot.GetBuffer(BUFFERLEN);
  1304. if (lpsz != NULL)
  1305. {
  1306. int iReturn = -1;
  1307. if (nWndDir != -1)
  1308. iReturn = GetWindowsDirectory(lpsz, BUFFERLEN);
  1309. else
  1310. iReturn = GetEnvironmentVariable(MMC_SYSTEMROOT_VARIABLE, lpsz, BUFFERLEN);
  1311. // release string buffer
  1312. strRoot.ReleaseBuffer();
  1313. // Build up new target string based on environemnt variable.
  1314. if (iReturn != 0)
  1315. {
  1316. strRet = strTarget.Left(nStpos);
  1317. strRet += strRoot;
  1318. strRet += strTarget.Mid(nStpos + nLen, strTarget.GetLength() - (nStpos + nLen));
  1319. }
  1320. }
  1321. }
  1322. USES_CONVERSION;
  1323. *ppViewType = (LPOLESTR)CoTaskMemAlloc( (_tcslen(strRet)+1) * sizeof(OLECHAR) );
  1324. *pViewOptions = GetComponentData()->GetDescriptor().GetViewOptions();
  1325. wcscpy(*ppViewType, T2COLE(strRet));
  1326. return sc.ToHr();
  1327. }
  1328. //############################################################################
  1329. //############################################################################
  1330. //
  1331. // Implementation of class COCXSnapinData
  1332. //
  1333. //############################################################################
  1334. //############################################################################
  1335. STDMETHODIMP
  1336. COCXSnapinData::CreateComponent(LPCOMPONENT* ppComponent)
  1337. {
  1338. typedef CComObject<COCXSnapinComponent> CComponent;
  1339. CComponent * pComponent = NULL;
  1340. CComObject<COCXSnapinComponent>::CreateInstance(&pComponent);
  1341. ASSERT(pComponent != NULL);
  1342. if(pComponent == NULL)
  1343. {
  1344. //TraceError(TEXT("COCXSnapinData::CreateComponent"));
  1345. return E_UNEXPECTED;
  1346. }
  1347. pComponent->Init(this);
  1348. return pComponent->QueryInterface(IID_IComponent, (void **)ppComponent); // does the Addref.
  1349. }
  1350. COCXSnapinData::COCXSnapinData()
  1351. {
  1352. m_pActiveXPage0 = NULL;
  1353. m_pActiveXPage1 = NULL;
  1354. m_pActiveXPage2 = NULL;
  1355. m_iImage = eStockImage_OCX;
  1356. m_iOpenImage = eStockImage_OCX;
  1357. }
  1358. COCXSnapinData::~COCXSnapinData()
  1359. {
  1360. }
  1361. STDMETHODIMP
  1362. COCXSnapinData::Destroy()
  1363. {
  1364. if(m_pActiveXPage0 != NULL)
  1365. {
  1366. delete m_pActiveXPage0;
  1367. m_pActiveXPage0 = NULL;
  1368. }
  1369. if(m_pActiveXPage1 != NULL)
  1370. {
  1371. delete m_pActiveXPage1;
  1372. m_pActiveXPage1 = NULL;
  1373. }
  1374. if(m_pActiveXPage2 != NULL)
  1375. {
  1376. delete m_pActiveXPage2;
  1377. m_pActiveXPage2 = NULL;
  1378. }
  1379. return BC::Destroy();
  1380. }
  1381. const CLSID CLSID_OCXSnapin = {0xC96401CF, 0x0E17,0x11D3, {0x88,0x5B,0x00,0xC0,0x4F,0x72,0xC7,0x17}};
  1382. static const GUID GUID_OCXSnapinNodetype = {0xc96401d0, 0xe17, 0x11d3, { 0x88, 0x5b, 0x0, 0xc0, 0x4f, 0x72, 0xc7, 0x17 } };
  1383. static LPCTSTR szClsid_OCXSnapin = TEXT("{C96401CF-0E17-11D3-885B-00C04F72C717}");
  1384. static LPCTSTR szGuidOCXSnapinNodetype = TEXT("{C96401D0-0E17-11D3-885B-00C04F72C717}");
  1385. CSnapinDescriptor &
  1386. COCXSnapinData::GetSnapinDescriptor()
  1387. {
  1388. static CSnapinDescriptor snapinDescription(IDS_ACTIVEXCONTROL,
  1389. IDS_OCXSNAPIN_DESC, IDI_OCX, IDB_OCX_16, IDB_OCX_16, IDB_OCX_32,
  1390. CLSID_OCXSnapin, szClsid_OCXSnapin, GUID_OCXSnapinNodetype,
  1391. szGuidOCXSnapinNodetype, TEXT("OCX"), TEXT("Snapins.OCXSnapin"),
  1392. TEXT("Snapins.OCXSnapin.1"), MMC_VIEW_OPTIONS_NOLISTVIEWS /*viewOptions*/ );
  1393. return snapinDescription;
  1394. }
  1395. // IExtendPropertySheet2
  1396. STDMETHODIMP
  1397. COCXSnapinData::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, LPDATAOBJECT lpIDataObject)
  1398. {
  1399. HPROPSHEETPAGE hPage;
  1400. ASSERT(lpProvider != NULL);
  1401. if(lpProvider == NULL)
  1402. {
  1403. //TraceError(TEXT("CHTMLSnapinData::CreatePropertyPages"));
  1404. return E_UNEXPECTED;
  1405. }
  1406. ASSERT(m_pActiveXPage0 == NULL);
  1407. ASSERT(m_pActiveXPage1 == NULL);
  1408. ASSERT(m_pActiveXPage2 == NULL);
  1409. // create property pages
  1410. m_pActiveXPage0 = new CActiveXPage0;
  1411. m_pActiveXPage1 = new CActiveXPage1;
  1412. m_pActiveXPage2 = new CActiveXPage2;
  1413. // pass in pointer to data structure
  1414. m_pActiveXPage0->Initialize(this);
  1415. m_pActiveXPage1->Initialize(this);
  1416. m_pActiveXPage2->Initialize(this);
  1417. // Add Pages to property sheet
  1418. hPage=CreatePropertySheetPage(&m_pActiveXPage0->m_psp);
  1419. lpProvider->AddPage(hPage);
  1420. hPage=CreatePropertySheetPage(&m_pActiveXPage1->m_psp);
  1421. lpProvider->AddPage(hPage);
  1422. hPage=CreatePropertySheetPage(&m_pActiveXPage2->m_psp);
  1423. lpProvider->AddPage(hPage);
  1424. return S_OK;
  1425. }
  1426. //############################################################################
  1427. //############################################################################
  1428. //
  1429. // Implementation of class COCXSnapinComponent
  1430. //
  1431. //############################################################################
  1432. //############################################################################
  1433. /*+-------------------------------------------------------------------------*
  1434. *
  1435. * COCXSnapinComponent::Notify
  1436. *
  1437. * PURPOSE: Implements the CComponent::Notify method
  1438. *
  1439. * PARAMETERS:
  1440. * LPDATAOBJECT lpDataObject :
  1441. * MMC_NOTIFY_TYPE event :
  1442. * LPARAM arg :
  1443. * LPARAM param :
  1444. *
  1445. * RETURNS:
  1446. * HRESULT
  1447. *
  1448. *+-------------------------------------------------------------------------*/
  1449. HRESULT
  1450. COCXSnapinComponent::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  1451. {
  1452. HRESULT hr = S_OK;
  1453. switch(event)
  1454. {
  1455. // Handle just the OCX initialization notify
  1456. case MMCN_INITOCX:
  1457. return OnInitOCX(lpDataObject, arg, param);
  1458. break;
  1459. default:
  1460. // Pass other notifications on to base class
  1461. return CSnapinComponentImpl::Notify(lpDataObject, event, arg, param);
  1462. break;
  1463. }
  1464. return hr;
  1465. }
  1466. /*+-------------------------------------------------------------------------*
  1467. *
  1468. * COCXSnapinComponent::OnInitOCX
  1469. *
  1470. * PURPOSE: Handles the MMCN_INITOCX message.
  1471. *
  1472. * PARAMETERS:
  1473. * LPDATAOBJECT lpDataObject :
  1474. * LPARAM arg :
  1475. * LPARAM param :
  1476. *
  1477. * RETURNS:
  1478. * HRESULT
  1479. *
  1480. *+-------------------------------------------------------------------------*/
  1481. HRESULT
  1482. COCXSnapinComponent::OnInitOCX(LPDATAOBJECT lpDataObject, LPARAM arg, LPARAM param)
  1483. {
  1484. HRESULT hr = S_OK;
  1485. ASSERT(param != NULL);
  1486. IUnknown* pUnknown = reinterpret_cast<IUnknown*>(param);
  1487. ASSERT(m_bLoaded || m_bInitialized);
  1488. // Load or initialze the OCX
  1489. if (m_bLoaded || m_bInitialized)
  1490. {
  1491. IPersistStreamInitPtr spIPStmInit;
  1492. // Query for stream support
  1493. m_spIPStm = pUnknown;
  1494. // if none, try streamInit
  1495. if (m_spIPStm == NULL)
  1496. {
  1497. spIPStmInit = pUnknown;
  1498. // if streamInit found, cast to normal stream pointer
  1499. // so common methods can be called from single pointer
  1500. if (spIPStmInit != NULL)
  1501. m_spIPStm = (IPersistStream*)spIPStmInit.GetInterfacePtr();
  1502. }
  1503. // if either type of stream persistance supported
  1504. if (m_spIPStm != NULL)
  1505. {
  1506. // if load method was called, then ask OCX to load from inner stream
  1507. // Note that inner stream will not exist if OCX was never created
  1508. if (m_bLoaded)
  1509. {
  1510. IStreamPtr spStm;
  1511. HRESULT hr2 = m_spStg->OpenStream(SZ_OCXSTREAM, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, NULL, &spStm);
  1512. if (SUCCEEDED(hr2))
  1513. hr = m_spIPStm->Load(spStm);
  1514. else
  1515. m_bLoaded = FALSE;
  1516. }
  1517. // if no load was done and OCX requires an InitNew, give it one now
  1518. if (!m_bLoaded && spIPStmInit != NULL)
  1519. hr = spIPStmInit->InitNew();
  1520. }
  1521. else
  1522. {
  1523. // Query for storage support
  1524. m_spIPStg = pUnknown;
  1525. // if storage supported, ask OCX to load from inner storage
  1526. // Note that inner storage will not exist if OCX was never created
  1527. if (m_spIPStg != NULL)
  1528. {
  1529. if (m_bLoaded)
  1530. {
  1531. ASSERT(m_spStgInner == NULL);
  1532. HRESULT hr2 = m_spStg->OpenStorage(SZ_OCXSTORAGE, NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE,
  1533. NULL, NULL, &m_spStgInner);
  1534. if (SUCCEEDED(hr2))
  1535. hr = m_spIPStg->Load(m_spStgInner);
  1536. else
  1537. m_bLoaded = FALSE;
  1538. }
  1539. // if no load done, create an inner storage and init from it
  1540. if (!m_bLoaded)
  1541. {
  1542. ASSERT(m_spStgInner == NULL);
  1543. hr = m_spStg->CreateStorage(SZ_OCXSTORAGE, STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL,
  1544. NULL, &m_spStgInner);
  1545. if (SUCCEEDED(hr))
  1546. hr = m_spIPStg->InitNew(m_spStgInner);
  1547. }
  1548. }
  1549. }
  1550. }
  1551. return hr;
  1552. }
  1553. STDMETHODIMP COCXSnapinComponent::InitNew(IStorage* pStg)
  1554. {
  1555. if (pStg == NULL)
  1556. return E_POINTER;
  1557. if (m_bInitialized)
  1558. return CO_E_ALREADYINITIALIZED;
  1559. // Hold onto storage
  1560. m_spStg = pStg;
  1561. m_bInitialized = TRUE;
  1562. return S_OK;
  1563. }
  1564. HRESULT COCXSnapinComponent::Load(IStorage* pStg)
  1565. {
  1566. if (pStg == NULL)
  1567. return E_POINTER;
  1568. if (m_bInitialized)
  1569. return CO_E_ALREADYINITIALIZED;
  1570. // Hold onto storage
  1571. m_spStg = pStg;
  1572. m_bLoaded = TRUE;
  1573. m_bInitialized = TRUE;
  1574. return S_OK;
  1575. }
  1576. HRESULT COCXSnapinComponent::IsDirty()
  1577. {
  1578. HRESULT hr = S_FALSE;
  1579. if (m_spIPStm != NULL)
  1580. {
  1581. hr = m_spIPStm->IsDirty();
  1582. }
  1583. else if (m_spIPStg != NULL)
  1584. {
  1585. hr = m_spIPStg->IsDirty();
  1586. }
  1587. return hr;
  1588. }
  1589. HRESULT COCXSnapinComponent::Save(IStorage* pStg, BOOL fSameAsLoad)
  1590. {
  1591. DECLARE_SC(sc, TEXT("COCXSnapinComponent::Save"));
  1592. // parameter check
  1593. sc = ScCheckPointers( pStg );
  1594. if (sc)
  1595. return sc.ToHr();
  1596. // to be able to save we need to be initialized
  1597. sc = ScCheckPointers( m_spStg, E_UNEXPECTED );
  1598. if (sc)
  1599. return sc.ToHr();
  1600. // if need to use the new storage - make a copy
  1601. if (!fSameAsLoad)
  1602. {
  1603. sc = m_spStg->CopyTo(0, NULL, NULL, pStg);
  1604. if (sc)
  1605. return sc.ToHr();
  1606. // release cached storage (in case we have it) - it must change
  1607. m_spStgInner = NULL;
  1608. // hold onto the new storage
  1609. m_spStg = pStg;
  1610. // assignment uses QI - recheck!
  1611. sc = ScCheckPointers( m_spStg, E_UNEXPECTED );
  1612. if (sc)
  1613. return sc.ToHr();
  1614. }
  1615. // if storage support, ask OCX to save to inner storage
  1616. if (m_spIPStg)
  1617. {
  1618. bool bSameStorageForSnapin = true;
  1619. // if saving to different storage, create new inner storage on it and pass to OCX
  1620. if ( m_spStgInner == NULL )
  1621. {
  1622. sc = pStg->CreateStorage(SZ_OCXSTORAGE, STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, NULL, NULL, &m_spStgInner);
  1623. if (sc)
  1624. return sc.ToHr();
  1625. bSameStorageForSnapin = false;
  1626. }
  1627. // recheck the pointer
  1628. sc = ScCheckPointers( m_spStgInner, E_UNEXPECTED );
  1629. if (sc)
  1630. return sc.ToHr();
  1631. // save to the storage
  1632. sc = m_spIPStg->Save( m_spStgInner, (fSameAsLoad && bSameStorageForSnapin) );
  1633. if (sc)
  1634. return sc.ToHr();
  1635. }
  1636. // else if stream support, create/open stream and save to it
  1637. else if (m_spIPStm)
  1638. {
  1639. // if stream support, create internal stream and pass to OCX
  1640. IStreamPtr spStm;
  1641. sc = m_spStg->CreateStream(SZ_OCXSTREAM, STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, NULL, NULL, &spStm);
  1642. if (sc)
  1643. return sc.ToHr();
  1644. sc = m_spIPStm->Save(spStm, TRUE);
  1645. if (sc)
  1646. return sc.ToHr();
  1647. }
  1648. else
  1649. {
  1650. // we are here if the OCX was never created (i.e., this component never owned the result pane)
  1651. // if node was loaded and has to save to a new file, just copy the current storage to the new one
  1652. }
  1653. return sc.ToHr();
  1654. }
  1655. HRESULT COCXSnapinComponent::HandsOffStorage()
  1656. {
  1657. // Release storage if holding ref
  1658. // if ocx is holding storage, forward call to it
  1659. if (m_spIPStg != NULL && m_spStgInner != NULL)
  1660. m_spIPStg->HandsOffStorage();
  1661. // Free our own refs
  1662. m_spStgInner = NULL;
  1663. m_spStg = NULL;
  1664. return S_OK;
  1665. }
  1666. HRESULT COCXSnapinComponent::SaveCompleted(IStorage* pStgNew)
  1667. {
  1668. HRESULT hr = S_OK;
  1669. if (m_spIPStg != NULL)
  1670. {
  1671. // if new storage provided
  1672. if (pStgNew != NULL && pStgNew != m_spStg)
  1673. {
  1674. // Create new inner storage and give to OCX
  1675. IStoragePtr spStgInner;
  1676. hr = pStgNew->CreateStorage(SZ_OCXSTORAGE, STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, NULL, NULL, &spStgInner);
  1677. if (SUCCEEDED(hr))
  1678. hr = m_spIPStg->SaveCompleted(spStgInner);
  1679. // Free current inner storage and hold onto new one
  1680. m_spStgInner = spStgInner;
  1681. }
  1682. else
  1683. {
  1684. m_spIPStg->SaveCompleted(NULL);
  1685. }
  1686. }
  1687. if (pStgNew != NULL)
  1688. m_spStg = pStgNew;
  1689. return hr;
  1690. }
  1691. HRESULT COCXSnapinComponent::GetClassID(CLSID *pClassID)
  1692. {
  1693. return E_NOTIMPL;
  1694. }