//+------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1994 - 1999 // // File: colwidth.h // // Contents: Classes related to column persistence. // // Classes: CColumnInfo, CColumnPersistInfo // CColumnsDlg. // // History: 14-Oct-98 AnandhaG Created // //-------------------------------------------------------------------- #ifndef COLWIDTH_H #define COLWIDTH_H #pragma once #pragma warning(disable: 4503) // Disable long name limit warnings #include "columninfo.h" using namespace std; class CColumnPersistInfo; class CColumnsDlg; // Column Persistence Versioning // Version 1 has // "Col index (seen by snapin)" "Width" "Format" in order. static const INT COLPersistenceVersion = 2; // We allow the list to grow COLUMNS_MAXLIMIT times more, // then we do garbage collection. #define COLUMNS_MAXLIMIT 0.4 //+------------------------------------------------------------------- // // Class: CColumnSortInfo // // Purpose: Columns sort information. // The column that is sorted and direction. // // History: 10-27-1998 AnandhaG Created // //-------------------------------------------------------------------- class CColumnSortInfo : public CSerialObject, public CXMLObject { public: friend class CColumnPersistInfo; friend class CNode; friend class CColumnsDlg; friend struct ColPosCompare; friend class CColumnData; public: CColumnSortInfo () : m_nCol(-1), m_dwSortOptions(0), m_lpUserParam(NULL) {} CColumnSortInfo (INT nCol, DWORD dwSortOptions) : m_nCol(nCol), m_dwSortOptions(dwSortOptions), m_lpUserParam(NULL) { } CColumnSortInfo(const CColumnSortInfo& colInfo) { m_nCol = colInfo.m_nCol; m_dwSortOptions = colInfo.m_dwSortOptions; m_lpUserParam = colInfo.m_lpUserParam; } CColumnSortInfo& operator=(const CColumnSortInfo& colInfo) { if (this != &colInfo) { m_nCol = colInfo.m_nCol; m_dwSortOptions = colInfo.m_dwSortOptions; m_lpUserParam = colInfo.m_lpUserParam; } return (*this); } bool operator ==(const CColumnSortInfo &colinfo) const { return ( (m_nCol == colinfo.m_nCol) && (m_dwSortOptions == colinfo.m_dwSortOptions) && (m_lpUserParam == colinfo.m_lpUserParam) ); } INT getColumn() const { return m_nCol;} DWORD getSortOptions() const { return m_dwSortOptions;} ULONG_PTR getUserParam() const { return m_lpUserParam;} protected: INT m_nCol; // The index supplied when snapin inserted the column. // This is not the index viewed by the user. DWORD m_dwSortOptions; // Sort flags like Ascending/Descending, Sort icon... ULONG_PTR m_lpUserParam; // Snapin supplied user param. protected: // CSerialObject methods virtual UINT GetVersion() {return 2;} virtual HRESULT ReadSerialObject (IStream &stm, UINT nVersion /*,LARGE_INTEGER nBytes*/); protected: DEFINE_XML_TYPE(XML_TAG_COLUMN_SORT_INFO); virtual void Persist(CPersistor &persistor); }; //+------------------------------------------------------------------- // // Class: CColumnSortList // // Purpose: linked list with CColumnInfo's. // // History: 02-11-1999 AnandhaG Created // //-------------------------------------------------------------------- class CColumnSortList : public list, public CSerialObject { public: friend class CColumnSetData; public: CColumnSortList () { } ~CColumnSortList() { } protected: void PersistSortList(CPersistor& persistor); // CSerialObject methods virtual UINT GetVersion() {return 1;} virtual HRESULT ReadSerialObject (IStream &stm, UINT nVersion /*,LARGE_INTEGER nBytes*/); }; //+------------------------------------------------------------------- // // Class: CColumnSetData // // Purpose: Data for a ColumnSetID. That is the data pertaining to // set of columns associated with a node. This data includes // column width, order, hidden/visible status. It also // includes the column on which we have sorted and the // order. // // History: 01-13-1998 AnandhaG Created // //-------------------------------------------------------------------- class CColumnSetData : public CSerialObject, public CXMLObject { public: friend class CColumnPersistInfo; friend class CColumnsDlg; public: CColumnSetData () { m_colInfoList.clear(); m_colSortList.clear(); m_dwRank = -1; m_bInvalid = FALSE; } ~CColumnSetData() { m_colInfoList.clear(); m_colSortList.clear(); m_dwRank = -1; m_bInvalid = FALSE; } CColumnSetData(const CColumnSetData& colSetInfo) { m_colInfoList = colSetInfo.m_colInfoList; m_colSortList = colSetInfo.m_colSortList; m_dwRank = colSetInfo.m_dwRank; m_bInvalid = FALSE; } CColumnSetData& operator=(const CColumnSetData& colSetInfo) { if (this != &colSetInfo) { m_colInfoList = colSetInfo.m_colInfoList; m_colSortList = colSetInfo.m_colSortList; m_dwRank = colSetInfo.m_dwRank; m_bInvalid = colSetInfo.m_bInvalid; } return (*this); } bool operator ==(const CColumnSetData &colinfo) const { return (false); } bool operator< (const CColumnSetData& colSetInfo) { return (m_dwRank < colSetInfo.m_dwRank); } CColumnInfoList* get_ColumnInfoList() { return &m_colInfoList; } void set_ColumnInfoList(const CColumnInfoList& colInfoList) { m_colInfoList = colInfoList; } CColumnSortList* get_ColumnSortList() { return &m_colSortList; } void set_ColumnSortList(CColumnSortList& colSortList) { m_colSortList = colSortList; } protected: // Needed for book keeping. DWORD m_dwRank; // Usage rank. BOOL m_bInvalid; // For garbage collection. protected: // Persisted data. CColumnInfoList m_colInfoList; CColumnSortList m_colSortList; protected: // CSerialObject methods // Version 2 had view settings removed. This data should be skipped while reading // version 1 files. virtual UINT GetVersion() {return 2;} virtual HRESULT ReadSerialObject (IStream &stm, UINT nVersion /*,LARGE_INTEGER nBytes*/); protected: DEFINE_XML_TYPE(XML_TAG_COLUMN_SET_DATA); virtual void Persist(CPersistor &persistor); }; typedef const BYTE * LPCBYTE; typedef std::vector ByteVector; //+------------------------------------------------------------------- // // Class: CColumnSetID // // Purpose: Identifier for a Column-Set. A a column-set is a set of // columns inserted by a snapin. When the user selects a // different node in that snapin same or different column-set /// may be shown by the snapin. MMC asks snapin to provide an // ID (either SColumnSetID or NodeTypeGuid) to uniquely identify // each column-set so that it can persist the column data. // This enables MMC to use this GUID to load and use the column // data across different instances,locales and systems. // // History: 02-08-1998 AnandhaG Created // //-------------------------------------------------------------------- class CColumnSetID : public CXMLObject { public: friend class CColumnPersistInfo; friend IStream& operator>> (IStream& stm, CColumnSetID& colID); friend IStream& operator<< (IStream& stm, const CColumnSetID& colID); private: void CommonConstruct (const SColumnSetID& refColID) { m_vID.clear(); m_dwFlags = refColID.dwFlags; m_vID.insert (m_vID.begin(), refColID.id, refColID.id + refColID.cBytes); } void CommonConstruct (const CLSID& clsidNodeType) { m_dwFlags = 0; BYTE* pbByte = (BYTE*)&clsidNodeType; if (pbByte != NULL) { m_vID.clear(); m_vID.insert (m_vID.begin(), pbByte, pbByte + sizeof(CLSID)); } } public: CColumnSetID() : m_dwFlags(0) { } ~CColumnSetID() {} CColumnSetID(LPCBYTE& pbInit) { // pbInit now points to a SColumnSetID; initialize from it const SColumnSetID* pColID = reinterpret_cast(pbInit); CommonConstruct (*pColID); // bump the input pointer to the next element pbInit += sizeof (pColID->cBytes) + pColID->cBytes; } CColumnSetID(const SColumnSetID& refColID) { CommonConstruct (refColID); } CColumnSetID(const CLSID& clsidNodeType) { CommonConstruct (clsidNodeType); } CColumnSetID(const CColumnSetID& colID) { m_dwFlags = colID.m_dwFlags; m_vID = colID.m_vID; } CColumnSetID& operator=(const CColumnSetID& colID) { if (this != &colID) { m_dwFlags = colID.m_dwFlags; m_vID = colID.m_vID; } return (*this); } bool operator ==(const CColumnSetID& colID) const { return (m_vID == colID.m_vID); } bool operator <(const CColumnSetID& colID) const { return (m_vID < colID.m_vID); } DWORD GetFlags() const { return m_dwFlags; } int empty () const { return (m_vID.empty()); } DEFINE_XML_TYPE(NULL); // not to be persisted as alone element virtual void Persist(CPersistor &persistor); protected: DWORD m_dwFlags; ByteVector m_vID; }; //+------------------------------------------------------------------- // // Member: operator>> // // Synopsis: Writes CColumnSetID data to stream. // // Arguments: [stm] - The input stream. // [colID] - CColumnSetID structure. // // The format is : // DWORD flags // ByteVector // //-------------------------------------------------------------------- inline IStream& operator>> (IStream& stm, CColumnSetID& colID) { return (stm >> colID.m_dwFlags >> colID.m_vID); } //+------------------------------------------------------------------- // // Member: operator<< // // Synopsis: Reads CColumnSortInfo data from the stream. // // Arguments: [stm] - The stream to write to. // [colID] - CColumnSetID structure. // // The format is : // DWORD flags // ByteVector // //-------------------------------------------------------------------- inline IStream& operator<< (IStream& stm, const CColumnSetID& colID) { return (stm << colID.m_dwFlags << colID.m_vID); } //+------------------------------------------------------------------- // // Data structures used to persist column information: // // Column information is persisted as follows: // Internally, the following data structure is used. Column information // is recorded per snapin, per column ID, per view. // map map map // CLSID ------> column ID ------> view ID -----> iterator to a list // containing data. // // The data itself is stored in an object of type CColumnSetData. // This has subobjects to store column width, column sorting, and view // options. // // The list contains CColumnSetData to all the views, all snapins // and all col-ids. // // Persistence: The information is serialized as follows: // // 1) Stream version // 2) Number of snapins // 3) For each snapin: // i) snapin CLSID // ii) number of column IDs // For each column ID: // i) column ID // ii) Number of views // For each view: // i) View ID // ii) Column data (CColumnSetData). //-------------------------------------------------------------------- //********************************************************************* // // Note: // The alpha compiler is unable to resolve long names and calls // wrong version of stl::map::erase (bug# 295465). // So we derive dummy classes like I1, V1, C1, S1 to shorten // those names. // // To repro the problem define _ALPHA_BUG_IN_MMC and compile mmc // // Classes: I1, V1, C1, S1 // // For version 2.0 the change was undone. But the names are not // long anymore, since classes are derived from maps (not typedef'ed) // //********************************************************************* //********************************************************************* // A list of all ColumnSet datas. typedef list ColSetDataList; typedef ColSetDataList::iterator ItColSetDataList; // A one to one map from ViewID to iterator to CColumnSetData. class ViewToColSetDataMap : public map { }; typedef ViewToColSetDataMap::value_type ViewToColSetDataVal; // A one to one map from CColumnSetID to ViewToColSetDataMap. class ColSetIDToViewTableMap : public map { }; typedef ColSetIDToViewTableMap::value_type ColSetIDToViewTableVal; // A one to one map from Snapin GUID to ColSetIDToToViewTableMap (snapins widthsets) class SnapinToColSetIDMap : public map { }; typedef SnapinToColSetIDMap::value_type SnapinToColSetIDVal; //+------------------------------------------------------------------- // // Some helper data structures that wont be persisted. // //-------------------------------------------------------------------- // A vector of strings to store column names typedef vector TStringVector; //+------------------------------------------------------------------- // // Class: CColumnPersistInfo // // Purpose: This class has column persistence information for all // views (therefore one per instance of mmc). // Knows to load/save the info from streams. // // History: 10-27-1998 AnandhaG Created // // Data structures used to persist column information: // A map from the ViewID to the CColumnSetData class. // A multimap from ColumnSet-ID to above map. // A map that maps snapin GUID to above map. // //-------------------------------------------------------------------- class CColumnPersistInfo : public IPersistStream, public CComObjectRoot, public CXMLObject { private: BOOL m_bInitialized; auto_ptr m_spColSetList; auto_ptr m_spSnapinsMap; // This is the max number of items specified by user??? // We go 40% more so that we dont do garbage collection often. DWORD m_dwMaxItems; BOOL m_bDirty; private: BOOL ClearAllEntries(); public: /* * ATL COM map */ BEGIN_COM_MAP (CColumnPersistInfo) COM_INTERFACE_ENTRY (IPersistStream) END_COM_MAP () public: CColumnPersistInfo(); ~CColumnPersistInfo(); BOOL Init(); BOOL RetrieveColumnData( const CLSID& refSnapinCLSID, const SColumnSetID& colID, INT nViewID, CColumnSetData& columnSetData); BOOL SaveColumnData( const CLSID& refSnapinCLSID, const SColumnSetID& colID, INT nViewID, CColumnSetData& columnSetData); VOID DeleteColumnData( const CLSID& refSnapinCLSID, const SColumnSetID& colID, INT nViewID); BOOL DeleteColumnDataOfSnapin( const CLSID& refSnapinCLSID); BOOL DeleteColumnDataOfView( int nViewID); VOID GarbageCollectItems(); VOID DeleteMarkedItems(); // IPersistStream methods STDMETHOD(IsDirty)(void) { if (m_bDirty) return S_OK; return S_FALSE; } STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize) { return E_NOTIMPL; } STDMETHOD(GetClassID)(LPCLSID lpClsid) { lpClsid = NULL; return E_NOTIMPL; } STDMETHOD(Load)(IStream *pStm); STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty); DEFINE_XML_TYPE(XML_TAG_COLUMN_PERIST_INFO); virtual void Persist(CPersistor &persistor); }; //+------------------------------------------------------------------- // // Class: CColumnDlg // // Purpose: The column modification dialog. // // History: 11-15-1998 AnandhaG Created // //-------------------------------------------------------------------- class CColumnsDlg : public CDialogImpl { typedef CColumnsDlg ThisClass; typedef CDialogImpl BaseClass; // Constructor/Destrcutor public: CColumnsDlg(CColumnInfoList *pColumnInfoList, TStringVector* pStringVector, CColumnInfoList& defaultColumnInfoList) : m_pColumnInfoList(pColumnInfoList), m_pStringVector(pStringVector), m_bDirty(false), m_DefaultColumnInfoList(defaultColumnInfoList), m_bUsingDefaultColumnSettings(false) {} ~CColumnsDlg() {} //MSGMAP public: BEGIN_MSG_MAP(ThisClass) MESSAGE_HANDLER (WM_INITDIALOG, OnInitDialog) CONTEXT_HELP_HANDLER() COMMAND_ID_HANDLER (IDOK, OnOK) COMMAND_ID_HANDLER (IDCANCEL, OnCancel) COMMAND_ID_HANDLER (IDC_MOVEUP_COLUMN, OnMoveUp) COMMAND_ID_HANDLER (IDC_MOVEDOWN_COLUMN , OnMoveDown) COMMAND_ID_HANDLER (IDC_ADD_COLUMNS, OnAdd) COMMAND_ID_HANDLER (IDC_REMOVE_COLUMNS, OnRemove) COMMAND_ID_HANDLER (IDC_RESTORE_DEFAULT_COLUMNS, OnRestoreDefaultColumns) COMMAND_HANDLER (IDC_HIDDEN_COLUMNS, LBN_SELCHANGE, OnSelChange); COMMAND_HANDLER (IDC_DISPLAYED_COLUMNS, LBN_SELCHANGE, OnSelChange); COMMAND_HANDLER (IDC_HIDDEN_COLUMNS, LBN_DBLCLK, OnAdd); COMMAND_HANDLER (IDC_DISPLAYED_COLUMNS, LBN_DBLCLK, OnRemove); END_MSG_MAP() IMPLEMENT_CONTEXT_HELP(g_aHelpIDs_IDD_COLUMNS); public: // Operators enum { IDD = IDD_COLUMNS }; // Generated message map functions protected: LRESULT OnInitDialog (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnOK (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnCancel (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnMoveUp (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnMoveDown (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnAdd (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnRemove (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnRestoreDefaultColumns (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnSelChange (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); private: void MoveItem (BOOL bMoveUp); void InitializeLists (); void EnableUIObjects (); int GetColIndex(LPCTSTR lpszColName); void SetListBoxHorizontalScrollbar(WTL::CListBox& listBox); void SetDirty() { m_bDirty = true; m_bUsingDefaultColumnSettings = false;} void SetUsingDefaultColumnSettings() { m_bDirty = true; m_bUsingDefaultColumnSettings = true;} bool EnableControl(HWND hwnd, bool bEnable); void SetListBoxHScrollSize() { SetListBoxHorizontalScrollbar(m_DisplayedColList); SetListBoxHorizontalScrollbar(m_HiddenColList); } private: WTL::CListBox m_HiddenColList; WTL::CListBox m_DisplayedColList; WTL::CButton m_btnAdd; WTL::CButton m_btnRemove; WTL::CButton m_btnRestoreDefaultColumns; WTL::CButton m_btnMoveUp; WTL::CButton m_btnMoveDown; CColumnInfoList* m_pColumnInfoList; TStringVector* m_pStringVector; CColumnInfoList& m_DefaultColumnInfoList; bool m_bDirty; bool m_bUsingDefaultColumnSettings; }; #endif /* COLWIDTH_H */