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.

684 lines
20 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1999
  5. //
  6. // File: colwidth.h
  7. //
  8. // Contents: Classes related to column persistence.
  9. //
  10. // Classes: CColumnInfo, CColumnPersistInfo
  11. // CColumnsDlg.
  12. //
  13. // History: 14-Oct-98 AnandhaG Created
  14. //
  15. //--------------------------------------------------------------------
  16. #ifndef COLWIDTH_H
  17. #define COLWIDTH_H
  18. #pragma once
  19. #pragma warning(disable: 4503) // Disable long name limit warnings
  20. #include "columninfo.h"
  21. using namespace std;
  22. class CColumnPersistInfo;
  23. class CColumnsDlg;
  24. // Column Persistence Versioning
  25. // Version 1 has
  26. // "Col index (seen by snapin)" "Width" "Format" in order.
  27. static const INT COLPersistenceVersion = 2;
  28. // We allow the list to grow COLUMNS_MAXLIMIT times more,
  29. // then we do garbage collection.
  30. #define COLUMNS_MAXLIMIT 0.4
  31. //+-------------------------------------------------------------------
  32. //
  33. // Class: CColumnSortInfo
  34. //
  35. // Purpose: Columns sort information.
  36. // The column that is sorted and direction.
  37. //
  38. // History: 10-27-1998 AnandhaG Created
  39. //
  40. //--------------------------------------------------------------------
  41. class CColumnSortInfo : public CSerialObject, public CXMLObject
  42. {
  43. public:
  44. friend class CColumnPersistInfo;
  45. friend class CNode;
  46. friend class CColumnsDlg;
  47. friend struct ColPosCompare;
  48. friend class CColumnData;
  49. public:
  50. CColumnSortInfo () : m_nCol(-1), m_dwSortOptions(0),
  51. m_lpUserParam(NULL)
  52. {}
  53. CColumnSortInfo (INT nCol, DWORD dwSortOptions)
  54. : m_nCol(nCol), m_dwSortOptions(dwSortOptions),
  55. m_lpUserParam(NULL)
  56. {
  57. }
  58. CColumnSortInfo(const CColumnSortInfo& colInfo)
  59. {
  60. m_nCol = colInfo.m_nCol;
  61. m_dwSortOptions = colInfo.m_dwSortOptions;
  62. m_lpUserParam = colInfo.m_lpUserParam;
  63. }
  64. CColumnSortInfo& operator=(const CColumnSortInfo& colInfo)
  65. {
  66. if (this != &colInfo)
  67. {
  68. m_nCol = colInfo.m_nCol;
  69. m_dwSortOptions = colInfo.m_dwSortOptions;
  70. m_lpUserParam = colInfo.m_lpUserParam;
  71. }
  72. return (*this);
  73. }
  74. bool operator ==(const CColumnSortInfo &colinfo) const
  75. {
  76. return ( (m_nCol == colinfo.m_nCol) &&
  77. (m_dwSortOptions == colinfo.m_dwSortOptions) &&
  78. (m_lpUserParam == colinfo.m_lpUserParam) );
  79. }
  80. INT getColumn() const { return m_nCol;}
  81. DWORD getSortOptions() const { return m_dwSortOptions;}
  82. ULONG_PTR getUserParam() const { return m_lpUserParam;}
  83. protected:
  84. INT m_nCol; // The index supplied when snapin inserted the column.
  85. // This is not the index viewed by the user.
  86. DWORD m_dwSortOptions; // Sort flags like Ascending/Descending, Sort icon...
  87. ULONG_PTR m_lpUserParam; // Snapin supplied user param.
  88. protected:
  89. // CSerialObject methods
  90. virtual UINT GetVersion() {return 2;}
  91. virtual HRESULT ReadSerialObject (IStream &stm, UINT nVersion /*,LARGE_INTEGER nBytes*/);
  92. protected:
  93. DEFINE_XML_TYPE(XML_TAG_COLUMN_SORT_INFO);
  94. virtual void Persist(CPersistor &persistor);
  95. };
  96. //+-------------------------------------------------------------------
  97. //
  98. // Class: CColumnSortList
  99. //
  100. // Purpose: linked list with CColumnInfo's.
  101. //
  102. // History: 02-11-1999 AnandhaG Created
  103. //
  104. //--------------------------------------------------------------------
  105. class CColumnSortList : public list<CColumnSortInfo>, public CSerialObject
  106. {
  107. public:
  108. friend class CColumnSetData;
  109. public:
  110. CColumnSortList ()
  111. {
  112. }
  113. ~CColumnSortList()
  114. {
  115. }
  116. protected:
  117. void PersistSortList(CPersistor& persistor);
  118. // CSerialObject methods
  119. virtual UINT GetVersion() {return 1;}
  120. virtual HRESULT ReadSerialObject (IStream &stm, UINT nVersion /*,LARGE_INTEGER nBytes*/);
  121. };
  122. //+-------------------------------------------------------------------
  123. //
  124. // Class: CColumnSetData
  125. //
  126. // Purpose: Data for a ColumnSetID. That is the data pertaining to
  127. // set of columns associated with a node. This data includes
  128. // column width, order, hidden/visible status. It also
  129. // includes the column on which we have sorted and the
  130. // order.
  131. //
  132. // History: 01-13-1998 AnandhaG Created
  133. //
  134. //--------------------------------------------------------------------
  135. class CColumnSetData : public CSerialObject, public CXMLObject
  136. {
  137. public:
  138. friend class CColumnPersistInfo;
  139. friend class CColumnsDlg;
  140. public:
  141. CColumnSetData ()
  142. {
  143. m_colInfoList.clear();
  144. m_colSortList.clear();
  145. m_dwRank = -1;
  146. m_bInvalid = FALSE;
  147. }
  148. ~CColumnSetData()
  149. {
  150. m_colInfoList.clear();
  151. m_colSortList.clear();
  152. m_dwRank = -1;
  153. m_bInvalid = FALSE;
  154. }
  155. CColumnSetData(const CColumnSetData& colSetInfo)
  156. {
  157. m_colInfoList = colSetInfo.m_colInfoList;
  158. m_colSortList = colSetInfo.m_colSortList;
  159. m_dwRank = colSetInfo.m_dwRank;
  160. m_bInvalid = FALSE;
  161. }
  162. CColumnSetData& operator=(const CColumnSetData& colSetInfo)
  163. {
  164. if (this != &colSetInfo)
  165. {
  166. m_colInfoList = colSetInfo.m_colInfoList;
  167. m_colSortList = colSetInfo.m_colSortList;
  168. m_dwRank = colSetInfo.m_dwRank;
  169. m_bInvalid = colSetInfo.m_bInvalid;
  170. }
  171. return (*this);
  172. }
  173. bool operator ==(const CColumnSetData &colinfo) const
  174. {
  175. return (false);
  176. }
  177. bool operator< (const CColumnSetData& colSetInfo)
  178. {
  179. return (m_dwRank < colSetInfo.m_dwRank);
  180. }
  181. CColumnInfoList* get_ColumnInfoList()
  182. {
  183. return &m_colInfoList;
  184. }
  185. void set_ColumnInfoList(const CColumnInfoList& colInfoList)
  186. {
  187. m_colInfoList = colInfoList;
  188. }
  189. CColumnSortList* get_ColumnSortList()
  190. {
  191. return &m_colSortList;
  192. }
  193. void set_ColumnSortList(CColumnSortList& colSortList)
  194. {
  195. m_colSortList = colSortList;
  196. }
  197. protected:
  198. // Needed for book keeping.
  199. DWORD m_dwRank; // Usage rank.
  200. BOOL m_bInvalid; // For garbage collection.
  201. protected:
  202. // Persisted data.
  203. CColumnInfoList m_colInfoList;
  204. CColumnSortList m_colSortList;
  205. protected:
  206. // CSerialObject methods
  207. // Version 2 had view settings removed. This data should be skipped while reading
  208. // version 1 files.
  209. virtual UINT GetVersion() {return 2;}
  210. virtual HRESULT ReadSerialObject (IStream &stm, UINT nVersion /*,LARGE_INTEGER nBytes*/);
  211. protected:
  212. DEFINE_XML_TYPE(XML_TAG_COLUMN_SET_DATA);
  213. virtual void Persist(CPersistor &persistor);
  214. };
  215. typedef const BYTE * LPCBYTE;
  216. typedef std::vector<BYTE> ByteVector;
  217. //+-------------------------------------------------------------------
  218. //
  219. // Class: CColumnSetID
  220. //
  221. // Purpose: Identifier for a Column-Set. A a column-set is a set of
  222. // columns inserted by a snapin. When the user selects a
  223. // different node in that snapin same or different column-set
  224. /// may be shown by the snapin. MMC asks snapin to provide an
  225. // ID (either SColumnSetID or NodeTypeGuid) to uniquely identify
  226. // each column-set so that it can persist the column data.
  227. // This enables MMC to use this GUID to load and use the column
  228. // data across different instances,locales and systems.
  229. //
  230. // History: 02-08-1998 AnandhaG Created
  231. //
  232. //--------------------------------------------------------------------
  233. class CColumnSetID : public CXMLObject
  234. {
  235. public:
  236. friend class CColumnPersistInfo;
  237. friend IStream& operator>> (IStream& stm, CColumnSetID& colID);
  238. friend IStream& operator<< (IStream& stm, const CColumnSetID& colID);
  239. private:
  240. void CommonConstruct (const SColumnSetID& refColID)
  241. {
  242. m_vID.clear();
  243. m_dwFlags = refColID.dwFlags;
  244. m_vID.insert (m_vID.begin(), refColID.id, refColID.id + refColID.cBytes);
  245. }
  246. void CommonConstruct (const CLSID& clsidNodeType)
  247. {
  248. m_dwFlags = 0;
  249. BYTE* pbByte = (BYTE*)&clsidNodeType;
  250. if (pbByte != NULL)
  251. {
  252. m_vID.clear();
  253. m_vID.insert (m_vID.begin(), pbByte, pbByte + sizeof(CLSID));
  254. }
  255. }
  256. public:
  257. CColumnSetID() : m_dwFlags(0)
  258. {
  259. }
  260. ~CColumnSetID() {}
  261. CColumnSetID(LPCBYTE& pbInit)
  262. {
  263. // pbInit now points to a SColumnSetID; initialize from it
  264. const SColumnSetID* pColID = reinterpret_cast<const SColumnSetID*>(pbInit);
  265. CommonConstruct (*pColID);
  266. // bump the input pointer to the next element
  267. pbInit += sizeof (pColID->cBytes) + pColID->cBytes;
  268. }
  269. CColumnSetID(const SColumnSetID& refColID)
  270. {
  271. CommonConstruct (refColID);
  272. }
  273. CColumnSetID(const CLSID& clsidNodeType)
  274. {
  275. CommonConstruct (clsidNodeType);
  276. }
  277. CColumnSetID(const CColumnSetID& colID)
  278. {
  279. m_dwFlags = colID.m_dwFlags;
  280. m_vID = colID.m_vID;
  281. }
  282. CColumnSetID& operator=(const CColumnSetID& colID)
  283. {
  284. if (this != &colID)
  285. {
  286. m_dwFlags = colID.m_dwFlags;
  287. m_vID = colID.m_vID;
  288. }
  289. return (*this);
  290. }
  291. bool operator ==(const CColumnSetID& colID) const
  292. {
  293. return (m_vID == colID.m_vID);
  294. }
  295. bool operator <(const CColumnSetID& colID) const
  296. {
  297. return (m_vID < colID.m_vID);
  298. }
  299. DWORD GetFlags() const { return m_dwFlags; }
  300. int empty () const { return (m_vID.empty()); }
  301. DEFINE_XML_TYPE(NULL); // not to be persisted as alone element
  302. virtual void Persist(CPersistor &persistor);
  303. protected:
  304. DWORD m_dwFlags;
  305. ByteVector m_vID;
  306. };
  307. //+-------------------------------------------------------------------
  308. //
  309. // Member: operator>>
  310. //
  311. // Synopsis: Writes CColumnSetID data to stream.
  312. //
  313. // Arguments: [stm] - The input stream.
  314. // [colID] - CColumnSetID structure.
  315. //
  316. // The format is :
  317. // DWORD flags
  318. // ByteVector
  319. //
  320. //--------------------------------------------------------------------
  321. inline IStream& operator>> (IStream& stm, CColumnSetID& colID)
  322. {
  323. return (stm >> colID.m_dwFlags >> colID.m_vID);
  324. }
  325. //+-------------------------------------------------------------------
  326. //
  327. // Member: operator<<
  328. //
  329. // Synopsis: Reads CColumnSortInfo data from the stream.
  330. //
  331. // Arguments: [stm] - The stream to write to.
  332. // [colID] - CColumnSetID structure.
  333. //
  334. // The format is :
  335. // DWORD flags
  336. // ByteVector
  337. //
  338. //--------------------------------------------------------------------
  339. inline IStream& operator<< (IStream& stm, const CColumnSetID& colID)
  340. {
  341. return (stm << colID.m_dwFlags << colID.m_vID);
  342. }
  343. //+-------------------------------------------------------------------
  344. //
  345. // Data structures used to persist column information:
  346. //
  347. // Column information is persisted as follows:
  348. // Internally, the following data structure is used. Column information
  349. // is recorded per snapin, per column ID, per view.
  350. // map map map
  351. // CLSID ------> column ID ------> view ID -----> iterator to a list
  352. // containing data.
  353. //
  354. // The data itself is stored in an object of type CColumnSetData.
  355. // This has subobjects to store column width, column sorting, and view
  356. // options.
  357. //
  358. // The list contains CColumnSetData to all the views, all snapins
  359. // and all col-ids.
  360. //
  361. // Persistence: The information is serialized as follows:
  362. //
  363. // 1) Stream version
  364. // 2) Number of snapins
  365. // 3) For each snapin:
  366. // i) snapin CLSID
  367. // ii) number of column IDs
  368. // For each column ID:
  369. // i) column ID
  370. // ii) Number of views
  371. // For each view:
  372. // i) View ID
  373. // ii) Column data (CColumnSetData).
  374. //--------------------------------------------------------------------
  375. //*********************************************************************
  376. //
  377. // Note:
  378. // The alpha compiler is unable to resolve long names and calls
  379. // wrong version of stl::map::erase (bug# 295465).
  380. // So we derive dummy classes like I1, V1, C1, S1 to shorten
  381. // those names.
  382. //
  383. // To repro the problem define _ALPHA_BUG_IN_MMC and compile mmc
  384. //
  385. // Classes: I1, V1, C1, S1
  386. //
  387. // For version 2.0 the change was undone. But the names are not
  388. // long anymore, since classes are derived from maps (not typedef'ed)
  389. //
  390. //*********************************************************************
  391. //*********************************************************************
  392. // A list of all ColumnSet datas.
  393. typedef list<CColumnSetData > ColSetDataList;
  394. typedef ColSetDataList::iterator ItColSetDataList;
  395. // A one to one map from ViewID to iterator to CColumnSetData.
  396. class ViewToColSetDataMap : public map<int /*nViewID*/, ItColSetDataList>
  397. {
  398. };
  399. typedef ViewToColSetDataMap::value_type ViewToColSetDataVal;
  400. // A one to one map from CColumnSetID to ViewToColSetDataMap.
  401. class ColSetIDToViewTableMap : public map<CColumnSetID, ViewToColSetDataMap>
  402. {
  403. };
  404. typedef ColSetIDToViewTableMap::value_type ColSetIDToViewTableVal;
  405. // A one to one map from Snapin GUID to ColSetIDToToViewTableMap (snapins widthsets)
  406. class SnapinToColSetIDMap : public map<CLSID, ColSetIDToViewTableMap>
  407. {
  408. };
  409. typedef SnapinToColSetIDMap::value_type SnapinToColSetIDVal;
  410. //+-------------------------------------------------------------------
  411. //
  412. // Some helper data structures that wont be persisted.
  413. //
  414. //--------------------------------------------------------------------
  415. // A vector of strings to store column names
  416. typedef vector<tstring> TStringVector;
  417. //+-------------------------------------------------------------------
  418. //
  419. // Class: CColumnPersistInfo
  420. //
  421. // Purpose: This class has column persistence information for all
  422. // views (therefore one per instance of mmc).
  423. // Knows to load/save the info from streams.
  424. //
  425. // History: 10-27-1998 AnandhaG Created
  426. //
  427. // Data structures used to persist column information:
  428. // A map from the ViewID to the CColumnSetData class.
  429. // A multimap from ColumnSet-ID to above map.
  430. // A map that maps snapin GUID to above map.
  431. //
  432. //--------------------------------------------------------------------
  433. class CColumnPersistInfo : public IPersistStream, public CComObjectRoot, public CXMLObject
  434. {
  435. private:
  436. BOOL m_bInitialized;
  437. auto_ptr<ColSetDataList> m_spColSetList;
  438. auto_ptr<SnapinToColSetIDMap> m_spSnapinsMap;
  439. // This is the max number of items specified by user???
  440. // We go 40% more so that we dont do garbage collection often.
  441. DWORD m_dwMaxItems;
  442. BOOL m_bDirty;
  443. private:
  444. BOOL ClearAllEntries();
  445. public:
  446. /*
  447. * ATL COM map
  448. */
  449. BEGIN_COM_MAP (CColumnPersistInfo)
  450. COM_INTERFACE_ENTRY (IPersistStream)
  451. END_COM_MAP ()
  452. public:
  453. CColumnPersistInfo();
  454. ~CColumnPersistInfo();
  455. BOOL Init();
  456. BOOL RetrieveColumnData( const CLSID& refSnapinCLSID, const SColumnSetID& colID,
  457. INT nViewID, CColumnSetData& columnSetData);
  458. BOOL SaveColumnData( const CLSID& refSnapinCLSID, const SColumnSetID& colID,
  459. INT nViewID, CColumnSetData& columnSetData);
  460. VOID DeleteColumnData( const CLSID& refSnapinCLSID, const SColumnSetID& colID,
  461. INT nViewID);
  462. BOOL DeleteColumnDataOfSnapin( const CLSID& refSnapinCLSID);
  463. BOOL DeleteColumnDataOfView( int nViewID);
  464. VOID GarbageCollectItems();
  465. VOID DeleteMarkedItems();
  466. // IPersistStream methods
  467. STDMETHOD(IsDirty)(void)
  468. {
  469. if (m_bDirty)
  470. return S_OK;
  471. return S_FALSE;
  472. }
  473. STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize)
  474. {
  475. return E_NOTIMPL;
  476. }
  477. STDMETHOD(GetClassID)(LPCLSID lpClsid)
  478. {
  479. lpClsid = NULL;
  480. return E_NOTIMPL;
  481. }
  482. STDMETHOD(Load)(IStream *pStm);
  483. STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty);
  484. DEFINE_XML_TYPE(XML_TAG_COLUMN_PERIST_INFO);
  485. virtual void Persist(CPersistor &persistor);
  486. };
  487. //+-------------------------------------------------------------------
  488. //
  489. // Class: CColumnDlg
  490. //
  491. // Purpose: The column modification dialog.
  492. //
  493. // History: 11-15-1998 AnandhaG Created
  494. //
  495. //--------------------------------------------------------------------
  496. class CColumnsDlg : public CDialogImpl<CColumnsDlg>
  497. {
  498. typedef CColumnsDlg ThisClass;
  499. typedef CDialogImpl<CColumnsDlg> BaseClass;
  500. // Constructor/Destrcutor
  501. public:
  502. CColumnsDlg(CColumnInfoList *pColumnInfoList, TStringVector* pStringVector, CColumnInfoList& defaultColumnInfoList)
  503. : m_pColumnInfoList(pColumnInfoList), m_pStringVector(pStringVector), m_bDirty(false),
  504. m_DefaultColumnInfoList(defaultColumnInfoList), m_bUsingDefaultColumnSettings(false)
  505. {}
  506. ~CColumnsDlg()
  507. {}
  508. //MSGMAP
  509. public:
  510. BEGIN_MSG_MAP(ThisClass)
  511. MESSAGE_HANDLER (WM_INITDIALOG, OnInitDialog)
  512. CONTEXT_HELP_HANDLER()
  513. COMMAND_ID_HANDLER (IDOK, OnOK)
  514. COMMAND_ID_HANDLER (IDCANCEL, OnCancel)
  515. COMMAND_ID_HANDLER (IDC_MOVEUP_COLUMN, OnMoveUp)
  516. COMMAND_ID_HANDLER (IDC_MOVEDOWN_COLUMN , OnMoveDown)
  517. COMMAND_ID_HANDLER (IDC_ADD_COLUMNS, OnAdd)
  518. COMMAND_ID_HANDLER (IDC_REMOVE_COLUMNS, OnRemove)
  519. COMMAND_ID_HANDLER (IDC_RESTORE_DEFAULT_COLUMNS, OnRestoreDefaultColumns)
  520. COMMAND_HANDLER (IDC_HIDDEN_COLUMNS, LBN_SELCHANGE, OnSelChange);
  521. COMMAND_HANDLER (IDC_DISPLAYED_COLUMNS, LBN_SELCHANGE, OnSelChange);
  522. COMMAND_HANDLER (IDC_HIDDEN_COLUMNS, LBN_DBLCLK, OnAdd);
  523. COMMAND_HANDLER (IDC_DISPLAYED_COLUMNS, LBN_DBLCLK, OnRemove);
  524. END_MSG_MAP()
  525. IMPLEMENT_CONTEXT_HELP(g_aHelpIDs_IDD_COLUMNS);
  526. public:
  527. // Operators
  528. enum { IDD = IDD_COLUMNS };
  529. // Generated message map functions
  530. protected:
  531. LRESULT OnInitDialog (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  532. LRESULT OnOK (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  533. LRESULT OnCancel (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  534. LRESULT OnMoveUp (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  535. LRESULT OnMoveDown (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  536. LRESULT OnAdd (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  537. LRESULT OnRemove (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  538. LRESULT OnRestoreDefaultColumns (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  539. LRESULT OnSelChange (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  540. LRESULT OnHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  541. private:
  542. void MoveItem (BOOL bMoveUp);
  543. void InitializeLists ();
  544. void EnableUIObjects ();
  545. int GetColIndex(LPCTSTR lpszColName);
  546. void SetListBoxHorizontalScrollbar(WTL::CListBox& listBox);
  547. void SetDirty() { m_bDirty = true; m_bUsingDefaultColumnSettings = false;}
  548. void SetUsingDefaultColumnSettings() { m_bDirty = true; m_bUsingDefaultColumnSettings = true;}
  549. void SetListBoxHScrollSize()
  550. {
  551. SetListBoxHorizontalScrollbar(m_DisplayedColList);
  552. SetListBoxHorizontalScrollbar(m_HiddenColList);
  553. }
  554. private:
  555. WTL::CListBox m_HiddenColList;
  556. WTL::CListBox m_DisplayedColList;
  557. WTL::CButton m_btnAdd;
  558. WTL::CButton m_btnRemove;
  559. WTL::CButton m_btnRestoreDefaultColumns;
  560. WTL::CButton m_btnMoveUp;
  561. WTL::CButton m_btnMoveDown;
  562. CColumnInfoList* m_pColumnInfoList;
  563. TStringVector* m_pStringVector;
  564. CColumnInfoList& m_DefaultColumnInfoList;
  565. bool m_bDirty;
  566. bool m_bUsingDefaultColumnSettings;
  567. };
  568. #endif /* COLWIDTH_H */