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.

747 lines
21 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // snapwork.h
  8. //
  9. // SYNOPSIS
  10. //
  11. // Declares classes for implementing an MMC Snap-In.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 02/19/2000 Original version.
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #ifndef SNAPWORK_H
  19. #define SNAPWORK_H
  20. #if _MSC_VER >= 1000
  21. #pragma once
  22. #endif
  23. #include "dlgcshlp.h"
  24. class SnapInControlbar;
  25. class SnapInView;
  26. ///////////////////////////////////////////////////////////////////////////////
  27. //
  28. // NAMESPACE
  29. //
  30. // SnapIn
  31. //
  32. // DESCRIPTION
  33. //
  34. // Contains various declarations for exception support.
  35. //
  36. ///////////////////////////////////////////////////////////////////////////////
  37. namespace SnapIn
  38. {
  39. // Check an HRESULT and throw an exception on error.
  40. inline void CheckError(HRESULT hr)
  41. {
  42. if (FAILED(hr)) { AfxThrowOleException(hr); }
  43. }
  44. // Throw a COleException containing the result of GetLastError().
  45. void AfxThrowLastError();
  46. // Used for overloading the global new operator below.
  47. struct throw_t { };
  48. const throw_t AfxThrow;
  49. };
  50. // Throws a CMemoryException on allocation failure.
  51. inline void* __cdecl operator new(size_t size, const SnapIn::throw_t&)
  52. {
  53. void* p = ::operator new(size);
  54. if (!p) { AfxThrowMemoryException(); }
  55. return p;
  56. }
  57. inline void __cdecl operator delete(void* p, const SnapIn::throw_t&)
  58. {
  59. ::operator delete(p);
  60. }
  61. // Macro to catch any exception and return an appropriate HRESULT.
  62. #define CATCH_AND_RETURN() \
  63. catch (CException* e) { \
  64. HRESULT hr = COleException::Process(e); \
  65. e->ReportError(); \
  66. e->Delete(); \
  67. return hr; \
  68. } \
  69. catch (...) { \
  70. return E_FAIL; \
  71. }
  72. // Macro to catch any exception and store an appropriate HRESULT in hr.
  73. #define CATCH_AND_SAVE(hr) \
  74. catch (CException* e) { \
  75. hr = COleException::Process(e); \
  76. e->ReportError(); \
  77. e->Delete(); \
  78. } \
  79. catch (...) { \
  80. hr = E_FAIL; \
  81. }
  82. ///////////////////////////////////////////////////////////////////////////////
  83. //
  84. // CLASS
  85. //
  86. // ResourceString
  87. //
  88. // DESCRIPTION
  89. //
  90. // Simple wrapper around a string resource. Unlike most other wrappers this
  91. // can support strings of arbitrary length.
  92. //
  93. ///////////////////////////////////////////////////////////////////////////////
  94. class ResourceString
  95. {
  96. public:
  97. ResourceString(UINT id) throw ();
  98. ~ResourceString() throw ()
  99. { if (sz != &empty) delete[] sz; }
  100. operator PCWSTR() const throw ()
  101. { return sz; }
  102. operator PWSTR() throw ()
  103. { return sz; }
  104. private:
  105. PWSTR sz; // The string.
  106. static WCHAR empty; // Ensures that a ResourceString is never NULL.
  107. // Not implemented.
  108. ResourceString(const ResourceString&);
  109. ResourceString& operator=(const ResourceString&);
  110. };
  111. ///////////////////////////////////////////////////////////////////////////////
  112. //
  113. // Methods for manipulating a generic IDataObject (i.e., not necessarily one of
  114. // ours).
  115. //
  116. ///////////////////////////////////////////////////////////////////////////////
  117. // Extract a fixed number of bytes from an IDataObject.
  118. VOID
  119. WINAPI
  120. ExtractData(
  121. IDataObject* dataObject,
  122. CLIPFORMAT format,
  123. PVOID data,
  124. DWORD dataLen
  125. );
  126. // Extract a variable number of bytes. The caller must use GlobalFree to free
  127. // the returned data.
  128. VOID
  129. WINAPI
  130. ExtractData(
  131. IDataObject* dataObject,
  132. CLIPFORMAT format,
  133. DWORD maxDataLen,
  134. HGLOBAL* data
  135. );
  136. // Extract a node type GUID from an IDataObject.
  137. VOID
  138. WINAPI
  139. ExtractNodeType(
  140. IDataObject* dataObject,
  141. GUID* nodeType
  142. );
  143. ///////////////////////////////////////////////////////////////////////////////
  144. //
  145. // CLASS
  146. //
  147. // SnapInDataItem
  148. //
  149. // DESCRIPTION
  150. //
  151. // Abstract base class for items that will be displayed in the MMC scope
  152. // pane or result pane. When overriding functions, pay careful attention to
  153. // which ones are allowed to throw exceptions.
  154. //
  155. ///////////////////////////////////////////////////////////////////////////////
  156. class __declspec(uuid("af0af65a-abe0-4f47-9540-328351c23fab")) SnapInDataItem;
  157. class SnapInDataItem : public IDataObject
  158. {
  159. public:
  160. SnapInDataItem() throw ()
  161. : refCount(0)
  162. { }
  163. // Convert an IDataObject to its corresponding SnapInDataItem.
  164. static SnapInDataItem* narrow(IDataObject* dataObject) throw ();
  165. // Must be defined in the derived class to return the item's display name.
  166. virtual PCWSTR getDisplayName(int column = 0) const throw () = 0;
  167. // These should be overridden in the derived class unless you're sure MMC
  168. // will never ask for them.
  169. virtual const GUID* getNodeType() const throw ();
  170. virtual const GUID* getSnapInCLSID() const throw ();
  171. virtual PCWSTR getSZNodeType() const throw ();
  172. // Used to determine the sort order of two items.
  173. virtual int compare(
  174. SnapInDataItem& item,
  175. int column
  176. ) throw ();
  177. // Allows an item to add commands to the context menu.
  178. virtual HRESULT addMenuItems(
  179. SnapInView& view,
  180. LPCONTEXTMENUCALLBACK callback,
  181. long insertionAllowed
  182. );
  183. // Methods for exposing properties.
  184. virtual HRESULT createPropertyPages(
  185. SnapInView& view,
  186. LPPROPERTYSHEETCALLBACK provider,
  187. LONG_PTR handle
  188. );
  189. virtual HRESULT queryPagesFor() throw ();
  190. // Allows a scope item to customize the result view type.
  191. virtual HRESULT getResultViewType(
  192. LPOLESTR* ppViewType,
  193. long* pViewOptions
  194. ) throw ();
  195. //////////
  196. // Various notifications that your item can handle.
  197. //////////
  198. virtual HRESULT onButtonClick(
  199. SnapInView& view,
  200. MMC_CONSOLE_VERB verb
  201. );
  202. virtual HRESULT onContextHelp(
  203. SnapInView& view
  204. );
  205. virtual HRESULT onDelete(
  206. SnapInView& view
  207. );
  208. virtual HRESULT onDoubleClick(
  209. SnapInView& view
  210. );
  211. virtual HRESULT onExpand(
  212. SnapInView& view,
  213. HSCOPEITEM itemId,
  214. BOOL expanded
  215. );
  216. virtual HRESULT onMenuCommand(
  217. SnapInView& view,
  218. long commandId
  219. );
  220. virtual HRESULT onPropertyChange(
  221. SnapInView& view,
  222. BOOL scopeItem
  223. );
  224. virtual HRESULT onRefresh(
  225. SnapInView& view
  226. );
  227. virtual HRESULT onRename(
  228. SnapInView& view,
  229. LPCOLESTR newName
  230. );
  231. virtual HRESULT onSelect(
  232. SnapInView& view,
  233. BOOL scopeItem,
  234. BOOL selected
  235. );
  236. virtual HRESULT onShow(
  237. SnapInView& view,
  238. HSCOPEITEM itemId,
  239. BOOL selected
  240. );
  241. virtual HRESULT onToolbarButtonClick(
  242. SnapInView& view,
  243. int buttonId
  244. );
  245. virtual HRESULT onToolbarSelect(
  246. SnapInView& view,
  247. BOOL scopeItem,
  248. BOOL selected
  249. );
  250. virtual HRESULT onViewChange(
  251. SnapInView& view,
  252. LPARAM data,
  253. LPARAM hint
  254. );
  255. //////////
  256. // IUnknown
  257. //////////
  258. STDMETHOD_(ULONG, AddRef)();
  259. STDMETHOD_(ULONG, Release)();
  260. STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
  261. //////////
  262. // IDataObject
  263. //////////
  264. STDMETHOD(GetData)(
  265. FORMATETC *pformatetcIn,
  266. STGMEDIUM *pmedium
  267. );
  268. STDMETHOD(GetDataHere)(
  269. FORMATETC *pformatetc,
  270. STGMEDIUM *pmedium
  271. );
  272. STDMETHOD(QueryGetData)(FORMATETC *pformatetc);
  273. STDMETHOD(GetCanonicalFormatEtc)(
  274. FORMATETC *pformatectIn,
  275. FORMATETC *pformatetcOut
  276. );
  277. STDMETHOD(SetData)(
  278. FORMATETC *pformatetc,
  279. STGMEDIUM *pmedium,
  280. BOOL fRelease
  281. );
  282. STDMETHOD(EnumFormatEtc)(
  283. DWORD dwDirection,
  284. IEnumFORMATETC **ppenumFormatEtc
  285. );
  286. STDMETHOD(DAdvise)(
  287. FORMATETC *pformatetc,
  288. DWORD advf,
  289. IAdviseSink *pAdvSink,
  290. DWORD *pdwConnection
  291. );
  292. STDMETHOD(DUnadvise)(
  293. DWORD dwConnection
  294. );
  295. STDMETHOD(EnumDAdvise)(
  296. IEnumSTATDATA **ppenumAdvise
  297. );
  298. protected:
  299. virtual ~SnapInDataItem() throw ();
  300. private:
  301. LONG refCount;
  302. // Not implemented.
  303. SnapInDataItem(const SnapInDataItem&);
  304. SnapInDataItem& operator=(const SnapInDataItem&);
  305. };
  306. ///////////////////////////////////////////////////////////////////////////////
  307. //
  308. // CLASS
  309. //
  310. // SnapInPreNamedItem
  311. //
  312. // DESCRIPTION
  313. //
  314. // Extends SnapInDataItem to implement getDisplayName for items with a fixed
  315. // name that's stored in a string resource.
  316. //
  317. ///////////////////////////////////////////////////////////////////////////////
  318. class SnapInPreNamedItem : public SnapInDataItem
  319. {
  320. public:
  321. SnapInPreNamedItem(int nameId) throw ()
  322. : name(nameId)
  323. { }
  324. virtual PCWSTR getDisplayName(int column) const throw ();
  325. protected:
  326. ResourceString name;
  327. };
  328. ///////////////////////////////////////////////////////////////////////////////
  329. //
  330. // STRUCT
  331. //
  332. // SnapInToolbarDef
  333. //
  334. // DESCRIPTION
  335. //
  336. // Encapsulates the information needed to create and initialize a toolbar.
  337. // See IToolbar::AddImages and IToolbar::AddButtons for details. An array of
  338. // SnapInToolbarDef's must be terminated by an entry with nImages set to
  339. // zero.
  340. //
  341. ///////////////////////////////////////////////////////////////////////////////
  342. struct SnapInToolbarDef
  343. {
  344. int nImages;
  345. HBITMAP hbmp;
  346. COLORREF crMask;
  347. int nButtons;
  348. LPMMCBUTTON lpButtons;
  349. };
  350. ///////////////////////////////////////////////////////////////////////////////
  351. //
  352. // CLASS
  353. //
  354. // SnapInView
  355. //
  356. // DESCRIPTION
  357. //
  358. // Represents a view in the MMC console.
  359. //
  360. ///////////////////////////////////////////////////////////////////////////////
  361. class SnapInView
  362. : public CComObjectRootEx< CComMultiThreadModelNoCS >,
  363. public IComponent,
  364. public IComponentData,
  365. public IExtendContextMenu,
  366. public IExtendControlbar,
  367. public IExtendPropertySheet2,
  368. public IResultDataCompare,
  369. public ISnapinHelp
  370. {
  371. public:
  372. // Various interfaces for manipulating the view.
  373. // These are guaranteed to be non-NULL.
  374. IConsole2* getConsole() const throw ()
  375. { return console; }
  376. IHeaderCtrl2* getHeaderCtrl() const throw ()
  377. { return headerCtrl; }
  378. IConsoleNameSpace2* getNameSpace() const throw ()
  379. { return nameSpace; }
  380. IPropertySheetProvider* getPropertySheetProvider() const throw ()
  381. { return sheetProvider; }
  382. IResultData* getResultData() const throw ()
  383. { return resultData; }
  384. HRESULT displayHelp(PCWSTR contextHelpPath) throw();
  385. // Delete an item from the result pane.
  386. void deleteResultItem(const SnapInDataItem& item) const;
  387. // Update an item in the result pane.
  388. void updateResultItem(const SnapInDataItem& item) const;
  389. // Returns true if the item has a property sheet open.
  390. bool isPropertySheetOpen(const SnapInDataItem& item) const;
  391. // Attach a toolbar to the controlbar and return a pointer to the newly
  392. // attached toolbar so the caller can update button state, etc. The returned
  393. // pointer is only valid for the duration of the current notification method
  394. // and should not be released.
  395. IToolbar* attachToolbar(size_t index);
  396. // Detach a toolbar from the controlbar.
  397. void detachToolbar(size_t index) throw ();
  398. // Retrieve the current sort parameters.
  399. int getSortColumn() const throw ()
  400. { return sortColumn; }
  401. int getSortOption() const throw ()
  402. { return sortOption; }
  403. // Force a re-sort of the result pane using the current parameters.
  404. void reSort() const;
  405. // Format and display a dialog box.
  406. void formatMessageBox(
  407. UINT titleId,
  408. UINT formatId,
  409. BOOL ignoreInserts,
  410. UINT style,
  411. int* retval,
  412. ...
  413. );
  414. // Set the image strip associated with the scope or result pane.
  415. void setImageStrip(
  416. UINT smallStripId,
  417. UINT largeStripId,
  418. BOOL scopePane
  419. );
  420. // IUnknown.
  421. STDMETHOD_(ULONG, AddRef)();
  422. STDMETHOD_(ULONG, Release)();
  423. // IComponent
  424. STDMETHOD(Initialize)(LPCONSOLE lpConsole);
  425. STDMETHOD(Destroy)(MMC_COOKIE cookie);
  426. STDMETHOD(GetResultViewType)(
  427. MMC_COOKIE cookie,
  428. LPOLESTR* ppViewType,
  429. long* pViewOptions
  430. );
  431. STDMETHOD(GetDisplayInfo)(RESULTDATAITEM* pResultDataItem);
  432. // IComponentData
  433. STDMETHOD(Initialize)(LPUNKNOWN pUnknown);
  434. STDMETHOD(CreateComponent)(LPCOMPONENT* ppComponent);
  435. STDMETHOD(Destroy)();
  436. STDMETHOD(GetDisplayInfo)(SCOPEDATAITEM* pScopeDataItem);
  437. // Common to both IComponent and IComponentData
  438. STDMETHOD(QueryDataObject)(
  439. MMC_COOKIE cookie,
  440. DATA_OBJECT_TYPES type,
  441. LPDATAOBJECT* ppDataObject
  442. );
  443. STDMETHOD(Notify)(
  444. LPDATAOBJECT lpDataObject,
  445. MMC_NOTIFY_TYPE event,
  446. LPARAM arg,
  447. LPARAM param
  448. );
  449. STDMETHOD(CompareObjects)(
  450. LPDATAOBJECT lpDataObjectA,
  451. LPDATAOBJECT lpDataObjectB
  452. );
  453. // IExtendContextMenu
  454. STDMETHOD(AddMenuItems)(
  455. LPDATAOBJECT piDataObject,
  456. LPCONTEXTMENUCALLBACK piCallback,
  457. long *pInsertionAllowed
  458. );
  459. STDMETHOD(Command)(
  460. long lCommandID,
  461. LPDATAOBJECT piDataObject
  462. );
  463. // IExtendControlbar
  464. STDMETHOD(ControlbarNotify)(
  465. MMC_NOTIFY_TYPE event,
  466. LPARAM arg,
  467. LPARAM param
  468. );
  469. STDMETHOD(SetControlbar)(
  470. LPCONTROLBAR pControlbar
  471. );
  472. // IExtendPropertySheet
  473. STDMETHOD(CreatePropertyPages)(
  474. LPPROPERTYSHEETCALLBACK lpProvider,
  475. LONG_PTR handle,
  476. LPDATAOBJECT lpIDataObject
  477. );
  478. STDMETHOD(QueryPagesFor)(
  479. LPDATAOBJECT lpDataObject
  480. );
  481. // IExtendPropertySheet2
  482. STDMETHOD(GetWatermarks)(
  483. LPDATAOBJECT lpIDataObject,
  484. HBITMAP *lphWatermark,
  485. HBITMAP *lphHeader,
  486. HPALETTE *lphPalette,
  487. BOOL *bStretch
  488. );
  489. // IResultDataCompare
  490. STDMETHOD(Compare)(
  491. LPARAM lUserParam,
  492. MMC_COOKIE cookieA,
  493. MMC_COOKIE cookieB,
  494. int* pnResult
  495. );
  496. // ISnapinHelp method(s)
  497. STDMETHOD(GetHelpTopic)(LPOLESTR * lpCompiledHelpFile){return E_NOTIMPL;};
  498. protected:
  499. // Should be overridden by the derived class if it supports toolbars.
  500. virtual const SnapInToolbarDef* getToolbars() const throw ();
  501. SnapInView() throw ();
  502. ~SnapInView() throw ();
  503. BEGIN_COM_MAP(SnapInView)
  504. COM_INTERFACE_ENTRY_IID(__uuidof(IComponent), IComponent)
  505. COM_INTERFACE_ENTRY_IID(__uuidof(IComponentData), IComponentData)
  506. COM_INTERFACE_ENTRY_IID(__uuidof(IExtendContextMenu), IExtendContextMenu)
  507. COM_INTERFACE_ENTRY_IID(__uuidof(IExtendControlbar), IExtendControlbar)
  508. COM_INTERFACE_ENTRY_IID(__uuidof(IExtendPropertySheet2),
  509. IExtendPropertySheet2)
  510. COM_INTERFACE_ENTRY_IID(__uuidof(IResultDataCompare), IResultDataCompare)
  511. COM_INTERFACE_ENTRY_IID(__uuidof(ISnapinHelp), ISnapinHelp)
  512. END_COM_MAP()
  513. private:
  514. HRESULT internalInitialize(
  515. IConsoleNameSpace2* consoleNameSpace,
  516. SnapInView* masterView
  517. ) throw ();
  518. void releaseToolbars() throw ();
  519. // Struct that associates a toolbar definition with an instance of that
  520. // toolbar in the current view.
  521. struct ToolbarEntry
  522. {
  523. const SnapInToolbarDef* def;
  524. CComPtr<IToolbar> toolbar;
  525. };
  526. mutable CComPtr<IConsole2> console;
  527. mutable CComPtr<IConsoleNameSpace2> nameSpace;
  528. mutable CComPtr<IHeaderCtrl2> headerCtrl;
  529. mutable CComPtr<IPropertySheetProvider> sheetProvider;
  530. mutable CComPtr<IResultData> resultData;
  531. mutable CComPtr<IControlbar> controlbar;
  532. SnapInView* master;
  533. ToolbarEntry* toolbars;
  534. size_t numToolbars;
  535. int sortColumn;
  536. int sortOption;
  537. // Not implemented.
  538. SnapInView(const SnapInView&);
  539. SnapInView& operator=(const SnapInView&);
  540. };
  541. ///////////////////////////////////////////////////////////////////////////////
  542. //
  543. // CLASS
  544. //
  545. // SnapInPropertyPage
  546. //
  547. // DESCRIPTION
  548. //
  549. // Extends the MFC class CPropertyPageEx to handle the MMC specific details.
  550. //
  551. ///////////////////////////////////////////////////////////////////////////////
  552. class SnapInPropertyPage : public CHelpPageEx
  553. {
  554. public:
  555. // Constructor for MFC hosted page.
  556. SnapInPropertyPage(
  557. UINT nIDTemplate,
  558. UINT nIDHeaderTitle = 0,
  559. UINT nIDHeaderSubTitle = 0,
  560. bool EnableHelp = true
  561. );
  562. // Constructor for MMC hosted property page.
  563. SnapInPropertyPage(
  564. LONG_PTR notifyHandle,
  565. LPARAM notifyParam,
  566. bool deleteHandle,
  567. UINT nIDTemplate,
  568. UINT nIDCaption = 0,
  569. bool EnableHelp = true
  570. );
  571. ~SnapInPropertyPage() throw ();
  572. // Add the property page to a sheet. Regardless of whether or not this
  573. // succeeds, the SnapInPropertyPage is automatically deleted.
  574. void addToMMCSheet(IPropertySheetCallback* cback);
  575. // Returns 'true' if any changes have been applied.
  576. bool hasApplied() const throw ()
  577. { return applied; }
  578. // Returns 'true' if the page has been modified.
  579. bool isModified() const throw ()
  580. { return modified != FALSE; }
  581. // These should generally not be overridden.
  582. virtual void DoDataExchange(CDataExchange* pDX);
  583. virtual BOOL OnApply();
  584. virtual BOOL OnWizardFinish();
  585. virtual void OnReset();
  586. void SetModified(BOOL bChanged = TRUE);
  587. protected:
  588. // These should be overridden in the derived class to do the actual data and
  589. // UI processing.
  590. virtual void getData();
  591. virtual void setData();
  592. virtual void saveChanges();
  593. virtual void discardChanges();
  594. virtual UINT getErrorCaption() const throw () = 0;
  595. // Enable/disable a control on the page.
  596. void enableControl(int controlId, bool enable = true);
  597. // Fail a validation.
  598. void fail(int controlId, UINT errorText, bool isEdit = true);
  599. // Fail a validation, but don't throw an exception.
  600. void failNoThrow(int controlId, UINT errorText, bool isEdit = true);
  601. // Subclass a control member variable.
  602. void initControl(int controlId, CWnd& control);
  603. // Useful as a message handler.
  604. void onChange();
  605. // Display an error dialog.
  606. void reportError(UINT errorText);
  607. // Display an error dialog based on an exception. The exception is deleted.
  608. void reportException(CException* e);
  609. // Set the control to large font.
  610. void setLargeFont(int controlId);
  611. // Show/hide a control on the page.
  612. void showControl(int controlId, bool show = true);
  613. // Helper functions to get/set values from controls.
  614. void getValue(
  615. int controlId,
  616. LONG& value,
  617. UINT errorText
  618. );
  619. void setValue(
  620. int controlId,
  621. LONG value
  622. );
  623. void getValue(
  624. int controlId,
  625. bool& value
  626. );
  627. void setValue(
  628. int controlId,
  629. bool value
  630. );
  631. void getValue(
  632. int controlId,
  633. CComBSTR& value,
  634. bool trim = true
  635. );
  636. void setValue(
  637. int controlId,
  638. PCWSTR value
  639. );
  640. void getRadio(
  641. int firstId,
  642. int lastId,
  643. LONG& value
  644. );
  645. void setRadio(
  646. int firstId,
  647. int lastId,
  648. LONG value
  649. );
  650. static UINT CALLBACK propSheetPageProc(
  651. HWND hwnd,
  652. UINT uMsg,
  653. LPPROPSHEETPAGE ppsp
  654. ) throw ();
  655. LPFNPSPCALLBACK mfcCallback; // The MFC supplied PropSheetPageProc.
  656. LONG_PTR notify; // MMC notification handle
  657. LPARAM param; // MMC notification parameter
  658. bool owner; // 'true' if we own the handle
  659. bool applied; // 'true' if any changes have been applied.
  660. BOOL modified; // 'TRUE' if the page has been changed.
  661. };
  662. #define DEFINE_ERROR_CAPTION(id) \
  663. virtual UINT getErrorCaption() const throw () { return id; }
  664. #endif // SNAPWORK_H