Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

753 lines
22 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. void updateAllViews(
  386. SnapInDataItem& item,
  387. LPARAM data = 0,
  388. INT_PTR hint = 0
  389. ) const;
  390. // Delete an item from the result pane.
  391. void deleteResultItem(const SnapInDataItem& item) const;
  392. // Update an item in the result pane.
  393. void updateResultItem(const SnapInDataItem& item) const;
  394. // Returns true if the item has a property sheet open.
  395. bool isPropertySheetOpen(const SnapInDataItem& item) const;
  396. // Attach a toolbar to the controlbar and return a pointer to the newly
  397. // attached toolbar so the caller can update button state, etc. The returned
  398. // pointer is only valid for the duration of the current notification method
  399. // and should not be released.
  400. IToolbar* attachToolbar(size_t index);
  401. // Detach a toolbar from the controlbar.
  402. void detachToolbar(size_t index) throw ();
  403. // Retrieve the current sort parameters.
  404. int getSortColumn() const throw ()
  405. { return sortColumn; }
  406. int getSortOption() const throw ()
  407. { return sortOption; }
  408. // Force a re-sort of the result pane using the current parameters.
  409. void reSort() const;
  410. // Format and display a dialog box.
  411. void formatMessageBox(
  412. UINT titleId,
  413. UINT formatId,
  414. BOOL ignoreInserts,
  415. UINT style,
  416. int* retval,
  417. ...
  418. );
  419. // Set the image strip associated with the scope or result pane.
  420. void setImageStrip(
  421. UINT smallStripId,
  422. UINT largeStripId,
  423. BOOL scopePane
  424. );
  425. // IUnknown.
  426. STDMETHOD_(ULONG, AddRef)();
  427. STDMETHOD_(ULONG, Release)();
  428. // IComponent
  429. STDMETHOD(Initialize)(LPCONSOLE lpConsole);
  430. STDMETHOD(Destroy)(MMC_COOKIE cookie);
  431. STDMETHOD(GetResultViewType)(
  432. MMC_COOKIE cookie,
  433. LPOLESTR* ppViewType,
  434. long* pViewOptions
  435. );
  436. STDMETHOD(GetDisplayInfo)(RESULTDATAITEM* pResultDataItem);
  437. // IComponentData
  438. STDMETHOD(Initialize)(LPUNKNOWN pUnknown);
  439. STDMETHOD(CreateComponent)(LPCOMPONENT* ppComponent);
  440. STDMETHOD(Destroy)();
  441. STDMETHOD(GetDisplayInfo)(SCOPEDATAITEM* pScopeDataItem);
  442. // Common to both IComponent and IComponentData
  443. STDMETHOD(QueryDataObject)(
  444. MMC_COOKIE cookie,
  445. DATA_OBJECT_TYPES type,
  446. LPDATAOBJECT* ppDataObject
  447. );
  448. STDMETHOD(Notify)(
  449. LPDATAOBJECT lpDataObject,
  450. MMC_NOTIFY_TYPE event,
  451. LPARAM arg,
  452. LPARAM param
  453. );
  454. STDMETHOD(CompareObjects)(
  455. LPDATAOBJECT lpDataObjectA,
  456. LPDATAOBJECT lpDataObjectB
  457. );
  458. // IExtendContextMenu
  459. STDMETHOD(AddMenuItems)(
  460. LPDATAOBJECT piDataObject,
  461. LPCONTEXTMENUCALLBACK piCallback,
  462. long *pInsertionAllowed
  463. );
  464. STDMETHOD(Command)(
  465. long lCommandID,
  466. LPDATAOBJECT piDataObject
  467. );
  468. // IExtendControlbar
  469. STDMETHOD(ControlbarNotify)(
  470. MMC_NOTIFY_TYPE event,
  471. LPARAM arg,
  472. LPARAM param
  473. );
  474. STDMETHOD(SetControlbar)(
  475. LPCONTROLBAR pControlbar
  476. );
  477. // IExtendPropertySheet
  478. STDMETHOD(CreatePropertyPages)(
  479. LPPROPERTYSHEETCALLBACK lpProvider,
  480. LONG_PTR handle,
  481. LPDATAOBJECT lpIDataObject
  482. );
  483. STDMETHOD(QueryPagesFor)(
  484. LPDATAOBJECT lpDataObject
  485. );
  486. // IExtendPropertySheet2
  487. STDMETHOD(GetWatermarks)(
  488. LPDATAOBJECT lpIDataObject,
  489. HBITMAP *lphWatermark,
  490. HBITMAP *lphHeader,
  491. HPALETTE *lphPalette,
  492. BOOL *bStretch
  493. );
  494. // IResultDataCompare
  495. STDMETHOD(Compare)(
  496. LPARAM lUserParam,
  497. MMC_COOKIE cookieA,
  498. MMC_COOKIE cookieB,
  499. int* pnResult
  500. );
  501. // ISnapinHelp method(s)
  502. STDMETHOD(GetHelpTopic)(LPOLESTR * lpCompiledHelpFile){return E_NOTIMPL;};
  503. protected:
  504. // Should be overridden by the derived class if it supports toolbars.
  505. virtual const SnapInToolbarDef* getToolbars() const throw ();
  506. SnapInView() throw ();
  507. ~SnapInView() throw ();
  508. BEGIN_COM_MAP(SnapInView)
  509. COM_INTERFACE_ENTRY_IID(__uuidof(IComponent), IComponent)
  510. COM_INTERFACE_ENTRY_IID(__uuidof(IComponentData), IComponentData)
  511. COM_INTERFACE_ENTRY_IID(__uuidof(IExtendContextMenu), IExtendContextMenu)
  512. COM_INTERFACE_ENTRY_IID(__uuidof(IExtendControlbar), IExtendControlbar)
  513. COM_INTERFACE_ENTRY_IID(__uuidof(IExtendPropertySheet2),
  514. IExtendPropertySheet2)
  515. COM_INTERFACE_ENTRY_IID(__uuidof(IResultDataCompare), IResultDataCompare)
  516. COM_INTERFACE_ENTRY_IID(__uuidof(ISnapinHelp), ISnapinHelp)
  517. END_COM_MAP()
  518. private:
  519. HRESULT internalInitialize(
  520. IConsoleNameSpace2* consoleNameSpace,
  521. SnapInView* masterView
  522. ) throw ();
  523. void releaseToolbars() throw ();
  524. // Struct that associates a toolbar definition with an instance of that
  525. // toolbar in the current view.
  526. struct ToolbarEntry
  527. {
  528. const SnapInToolbarDef* def;
  529. CComPtr<IToolbar> toolbar;
  530. };
  531. mutable CComPtr<IConsole2> console;
  532. mutable CComPtr<IConsoleNameSpace2> nameSpace;
  533. mutable CComPtr<IHeaderCtrl2> headerCtrl;
  534. mutable CComPtr<IPropertySheetProvider> sheetProvider;
  535. mutable CComPtr<IResultData> resultData;
  536. mutable CComPtr<IControlbar> controlbar;
  537. SnapInView* master;
  538. ToolbarEntry* toolbars;
  539. size_t numToolbars;
  540. int sortColumn;
  541. int sortOption;
  542. // Not implemented.
  543. SnapInView(const SnapInView&);
  544. SnapInView& operator=(const SnapInView&);
  545. };
  546. ///////////////////////////////////////////////////////////////////////////////
  547. //
  548. // CLASS
  549. //
  550. // SnapInPropertyPage
  551. //
  552. // DESCRIPTION
  553. //
  554. // Extends the MFC class CPropertyPageEx to handle the MMC specific details.
  555. //
  556. ///////////////////////////////////////////////////////////////////////////////
  557. class SnapInPropertyPage : public CHelpPageEx
  558. {
  559. public:
  560. // Constructor for MFC hosted page.
  561. SnapInPropertyPage(
  562. UINT nIDTemplate,
  563. UINT nIDHeaderTitle = 0,
  564. UINT nIDHeaderSubTitle = 0,
  565. bool EnableHelp = true
  566. );
  567. // Constructor for MMC hosted property page.
  568. SnapInPropertyPage(
  569. LONG_PTR notifyHandle,
  570. LPARAM notifyParam,
  571. bool deleteHandle,
  572. UINT nIDTemplate,
  573. UINT nIDCaption = 0,
  574. bool EnableHelp = true
  575. );
  576. ~SnapInPropertyPage() throw ();
  577. // Add the property page to a sheet. Regardless of whether or not this
  578. // succeeds, the SnapInPropertyPage is automatically deleted.
  579. void addToMMCSheet(IPropertySheetCallback* cback);
  580. // Returns 'true' if any changes have been applied.
  581. bool hasApplied() const throw ()
  582. { return applied; }
  583. // Returns 'true' if the page has been modified.
  584. bool isModified() const throw ()
  585. { return modified != FALSE; }
  586. // These should generally not be overridden.
  587. virtual void DoDataExchange(CDataExchange* pDX);
  588. virtual BOOL OnApply();
  589. virtual BOOL OnWizardFinish();
  590. virtual void OnReset();
  591. void SetModified(BOOL bChanged = TRUE);
  592. protected:
  593. // These should be overridden in the derived class to do the actual data and
  594. // UI processing.
  595. virtual void getData();
  596. virtual void setData();
  597. virtual void saveChanges();
  598. virtual void discardChanges();
  599. virtual UINT getErrorCaption() const throw () = 0;
  600. // Enable/disable a control on the page.
  601. void enableControl(int controlId, bool enable = true);
  602. // Fail a validation.
  603. void fail(int controlId, UINT errorText, bool isEdit = true);
  604. // Fail a validation, but don't throw an exception.
  605. void failNoThrow(int controlId, UINT errorText, bool isEdit = true);
  606. // Subclass a control member variable.
  607. void initControl(int controlId, CWnd& control);
  608. // Useful as a message handler.
  609. void onChange();
  610. // Display an error dialog.
  611. void reportError(UINT errorText);
  612. // Display an error dialog based on an exception. The exception is deleted.
  613. void reportException(CException* e);
  614. // Set the control to large font.
  615. void setLargeFont(int controlId);
  616. // Show/hide a control on the page.
  617. void showControl(int controlId, bool show = true);
  618. // Helper functions to get/set values from controls.
  619. void getValue(
  620. int controlId,
  621. LONG& value,
  622. UINT errorText
  623. );
  624. void setValue(
  625. int controlId,
  626. LONG value
  627. );
  628. void getValue(
  629. int controlId,
  630. bool& value
  631. );
  632. void setValue(
  633. int controlId,
  634. bool value
  635. );
  636. void getValue(
  637. int controlId,
  638. CComBSTR& value,
  639. bool trim = true
  640. );
  641. void setValue(
  642. int controlId,
  643. PCWSTR value
  644. );
  645. void getRadio(
  646. int firstId,
  647. int lastId,
  648. LONG& value
  649. );
  650. void setRadio(
  651. int firstId,
  652. int lastId,
  653. LONG value
  654. );
  655. static UINT CALLBACK propSheetPageProc(
  656. HWND hwnd,
  657. UINT uMsg,
  658. LPPROPSHEETPAGE ppsp
  659. ) throw ();
  660. LPFNPSPCALLBACK mfcCallback; // The MFC supplied PropSheetPageProc.
  661. LONG_PTR notify; // MMC notification handle
  662. LPARAM param; // MMC notification parameter
  663. bool owner; // 'true' if we own the handle
  664. bool applied; // 'true' if any changes have been applied.
  665. BOOL modified; // 'TRUE' if the page has been changed.
  666. };
  667. #define DEFINE_ERROR_CAPTION(id) \
  668. virtual UINT getErrorCaption() const throw () { return id; }
  669. #endif // SNAPWORK_H