// ========================================================================== // Class Specification // COXHistoryCtrl // ========================================================================== // Version: 9.3 // This software along with its related components, documentation and files ("The Libraries") // is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is // governed by a software license agreement ("Agreement"). Copies of the Agreement are // available at The Code Project (www.codeproject.com), as part of the package you downloaded // to obtain this file, or directly from our office. For a copy of the license governing // this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900. // ////////////////////////////////////////////////////////////////////////// /* DESCRIPTION The COXHistoryCtrl class is COXScrollWnd based class which is designed to provide facilities to display and save log info (history info). We define log info as a set of entries (items) where each entry is displayed on new line. Every log entry (history entry, history item) is displayed on a single line. Optionally you can specify an offset for any such entry and also you can set text and background color that will be used to display an entry. Also you can add history entries that will be automatically time stamped. Scrolling of history items in the control is supported automatically through base COXScrollWnd class functionality. In order to avoid the over population of the control with history entries the max number of displayed items can be specified. When this number is reached and new entry is being added the item at the top will be removed. The contents of the control can be cleared at any time either. This class is thread safe. That means that you can safely populate it with new entries calling corresponding functions from different threads. Log info output can be also forwarded in a file. You might specify the name of the log file or alternatively choose to create a time stamped file that will be automatically named based on the day of creation (note that if an application that uses COXHistoryCtrl object runs longer then one day the multiple log files will be created for every day). Usage In order to use COXHistoryCtrl object in your application you have to create it using standard CWnd::Create function. After control was successfully created you might want to set options to save log info in a log file (if you don't care about log file you might skip this paragraph). In order to do that first of all you have to call the following function specifying TRUE as a parameter: void EnableLog(BOOL bYesNo); Then if you want to use time stamped log file you have to call: void EnableTimeStampedLog(BOOL bYesNo); and specify TRUE as a parameter. Otherwise you have to explicitly specify the name of the log file using: void SetLogFileName(CString sLogFileName); After you are done with creating the control and specifying log file options you can start populating the COXHistoryCtrl object using following functions: BOOL AddLine(CString string, BOOL bAddToLog=TRUE); BOOL AddStampedLine(CString string, BOOL bAddToLog=TRUE); BOOL AppendToLine(CString string, BOOL bAddToLog=TRUE); At any time the contents of the control can be cleared using: BOOL ClearHistory(); History control entries can be displayed using different text color and alignment and background color. Also you can specify an offset from the left side of the control's window client area that will be used while displaying a history entry. Use the following functions in order to specify these display options: void SetTextColor(COLORREF color); void SetBackColor(COLORREF color); void SetTextAlignment(int nAlignment); void SetOffset(int nOffset); Note that this function must be called before(!) adding new entries that must be displayed using new settings. Existing entries will not be affected by this functions. The sample that demonstrates COXHistoryCtrl class is called VisualStudioLikeDemo and can be found in the .\Samples\advanced\VisualStudioLikeDemo subdirectory of your Ultimate Toolbox directory. This is an advanced sample that demonstrates a lot of Ultimate Toolbox classes working together. History control examples are located in the bottom docking window (TabView container with "Build", "Debug", ... panes) Dependency: #include "OXHistoryCtrl.h" Source code files: "OXHistoryCtrl.cpp" "OXScrollWnd.cpp" - COXScrollWnd implementation */ #ifndef _OXHISTORYCTRL_H_ #define _OXHISTORYCTRL_H_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 #include "OXDllExt.h" #ifndef __AFXTEMPL_H__ #include #define __AFXTEMPL_H__ #endif #include "OXScrollWnd.h" #include "UTB64Bit.h" // history item descriptor typedef struct _tagHISTORYENTRY { // history item text CString m_sText; // item text color COLORREF m_clrText; // item background color COLORREF m_clrBack; // offset in points from the left side int m_nOffset; // text alignment. Refer for CDC::DrawText() function documentation // for details on possible values (nFormat parameter description) int m_nAlignment; // constructor _tagHISTORYENTRY(CString sText=_T(""), COLORREF clrText=GetSysColor(COLOR_WINDOWTEXT), COLORREF backColor=GetSysColor(COLOR_WINDOW), int nOffset=0, int nAlignment=DT_LEFT) { m_sText=sText; m_clrText=clrText; m_clrBack=backColor; m_nOffset=nOffset; m_nAlignment=nAlignment; } // assignment operator _tagHISTORYENTRY& operator=(const _tagHISTORYENTRY& entry) { if(this==&entry) return *this; m_sText=entry.m_sText; m_clrText=entry.m_clrText; m_clrBack=entry.m_clrBack; m_nOffset=entry.m_nOffset; m_nAlignment=entry.m_nAlignment; return *this; } } HISTORYENTRY; //history-logging control class class OX_CLASS_DECL COXHistoryCtrl : public COXScrollWnd { DECLARE_DYNCREATE(COXHistoryCtrl) public: // --- In : // --- Out : // --- Returns: // --- Effect: Constructs the object COXHistoryCtrl(); protected: // font to be used to display history items CFont m_font; //log file info // // filename of the log file CString m_sLogFileName; // flag that specifies that all history items will be saved in log file, // otherwise the history will be only displayed in the window BOOL m_bEnableLog; // flag that specifies that the log file should be automatically named depending // on the day it was created. That means that if the application that populates // history control runs for more then 1 day then for every day it runs new // log file will be created with cooresponding date. The filename format // is "ddmmyyyy". BOOL m_bTimeStampedLog; // if m_bEnableLog and m_bTimeStampedLog flags are set to TRUE then the new // log file will be automatically created for every day it runs (so if process // run for three days you will get three log files with filenames that specify // the date they were created in the format "ddmmyyyy") int m_logDay, m_logMonth, m_logYear; // log file CFile object CFile m_fileLog; // flag that specifies that if log file with specified name already exist it // will be truncated or new history entries will be added at the end of the // existing contents. By default it is set to TRUE (if log file exists its // contents will be cleared before adding new entry) BOOL m_bTruncateLogFile; // settings for displaying history items that will be added in future. That // means that whenever new history item is added we will use these parameters // to define text color, alignment and offset and background color // COLORREF m_clrText; COLORREF m_clrBack; COLORREF m_clrLeftOverBack; int m_nAlignment; int m_nOffset; // //////////////////////////// // the height of entry int m_nHeight; // the symbol size CSize m_sizeSymbol; // list of history items (entries) CList m_arrEntries; // the maximum number of entries that might be displayed in the control's // window. If this number is reached then whenever a new item is added the // one at the top is being removed. By default this number is set to 100. int m_nMaxNumEntries; //max line length int m_nMaxLengthEntry; // format string for displaying time stamp next to a history item (time // stamp will be automatically added to a history entry when you call // AddStampedLine() function). Refere to COleDateTime::Format function // for information on how this format string might look like CString m_sDateFormatString; // critical section variable, allows to populate history control from // different threads in a safe manner CRITICAL_SECTION m_criticalSection; public: // --- In : pFont - pointer to new font object // bRedraw - if TRUE the contents will be redrawn right away // --- Out : // --- Returns: // --- Effect: Sets new font to display history entries void SetFont(CFont* pFont, BOOL bRedraw=TRUE); // --- In : color - new text color // --- Out : // --- Returns: // --- Effect: Sets the text color for "will be added in future" history items. // New text color doesn't affect the existing history entries inline void SetTextColor(COLORREF color) { m_clrText=color; } // --- In : // --- Out : // --- Returns: Text color // --- Effect: Retrieves the current text color for "will be added in future" // history items. Whenever new history entry is added it uses // this value as its text color setting. inline COLORREF GetTextColor() const { return m_clrText; } // --- In : color - new background color // --- Out : // --- Returns: // --- Effect: Sets the background color for "will be added in future" history // items. New background color doesn't affect the existing history // entries inline void SetBackColor(COLORREF color) { m_clrBack=color; } // --- In : // --- Out : // --- Returns: Background color // --- Effect: Retrieves the current background color for "will be added in // future" history items. Whenever new history entry is added it uses // this value as its background color setting. inline COLORREF GetBackColor() const { return m_clrBack; } // --- In : color - new background color // --- Out : // --- Returns: // --- Effect: Sets the leftover background color. inline void SetLeftOverBackColor(COLORREF color) { m_clrLeftOverBack=color; } // --- In : // --- Out : // --- Returns: Leftover Background color // --- Effect: Retrieves the current leftover background color. inline COLORREF GetLeftOverBackColor() const { return m_clrLeftOverBack; } // --- In : nAlignment - new text alignment. It could take the same value // as nFormat parameter in CDC::DrawText() function // (DT_LEFT, DT_CENTER, DT_RIGHT) // --- Out : // --- Returns: // --- Effect: Sets the text alignment for "will be added in future" history // items. New text alignment doesn't affect the existing history // entries inline void SetTextAlignment(int nAlignment) { m_nAlignment=nAlignment; } // --- In : // --- Out : // --- Returns: Text alignment // --- Effect: Retrieves the current text alignment for "will be added in future" // history items. Whenever new history entry is added it uses // this value as its text alignment setting. inline int GetTextAlignment() const { return m_nAlignment; } // --- In : nOffset - new offset in pixels for history entries // --- Out : // --- Returns: // --- Effect: Sets the offset in pixels for "will be added in future" history // items. New offset doesn't affect the existing history entries inline void SetOffset(int nOffset) { m_nOffset=nOffset; } // --- In : // --- Out : // --- Returns: History item offset from the left side of the control // --- Effect: Retrieves the current offset in pixels for "will be added in // future" history items. Whenever new history entry is added it // uses this value as its offset setting. inline int GetOffset() const { return m_nOffset; } // --- In : sLogFileName - filename of the log file // --- Out : // --- Returns: // --- Effect: Sets the name of the log file. Note that if time stamped // log file is enabled then the log file will be named // automatically. Still the file extension will be retrieved // from this filename inline void SetLogFileName(CString sLogFileName) { m_sLogFileName=sLogFileName; } // --- In : // --- Out : // --- Returns: Filename of the log file // --- Effect: Retrieves the name of the log file. Note that if time stamped // log file is enabled then the log file will be named // automatically. Still the file extension will be retrieved // from this filename inline CString GetLogFileName() const { return m_sLogFileName; } // --- In : bYesNo - if TRUE then new history entries will be saved // in the log file, otherwise the log file will be // closed if any was opened before // --- Out : // --- Returns: // --- Effect: Enables/disables the output of the history entries in the // log file void EnableLog(BOOL bYesNo); // --- In : // --- Out : // --- Returns: TRUE if output in the log file is enabled or FALSE otherwise // --- Effect: Retrieves the flag that specifies if output of history entries is // enabled or disabled inline BOOL IsEnabledLog() const { return m_bEnableLog; } // --- In : bYesNo - if TRUE then log file will be automatically named // depending on the date it was created // (format "ddmmyyyy") // --- Out : // --- Returns: // --- Effect: Enables/disables the output of the history entries in the // time stamped (in terms of filename) log file inline void EnableTimeStampedLog(BOOL bYesNo) { m_bTimeStampedLog=bYesNo; } // --- In : // --- Out : // --- Returns: TRUE if log file is automatically named depending on the date // it was created (format "ddmmyyyy"), or FALSE otherwise // --- Effect: Retrieves the flag that defines if time stamped (in terms of // filename) log file is enabled or not inline BOOL IsEnabledTimeStamped() const { return m_bTimeStampedLog; } // --- In : bTruncateLogFile - flag that if set to TRUE will force // to truncate the contents of the existing // log file before adding new entry. // If FALSE specified then if log file // already exists then its contents will be // preserved and new entry will be added at // the end // --- Out : // --- Returns: // --- Effect: Sets the flag that specifies a truncate mode for existing log file inline void SetTruncateLogFile(BOOL bTruncateLogFile) { m_bTruncateLogFile=bTruncateLogFile; } // --- In : // --- Out : // --- Returns: flag that if set to TRUE will force to truncate the contents // of the existing log file before adding new entry. If FALSE // specified then if log file already exists then its contents // will be preserved and new entry will be added at the end // --- Effect: Retrieves the flag that specifies a truncate mode for existing // log file inline BOOL GetTruncateLogFile() const { return m_bTruncateLogFile; } // --- In : nMaxNum - the limit for the number of the history entries // displayed in the control's window // --- Out : // --- Returns: // --- Effect: Sets the maximum number of the history entries displayed // in the control's window. If this number is reached then // whenever a new item is added the one at the top is being removed. void SetMaxNumEntries(int nMaxNum); // --- In : // --- Out : // --- Returns: The limit for the number of the history entries displayed in the // control's window // --- Effect: Retrieves the maximum number of the history entries that can be // displayed in the control's window. If this number is reached then // whenever a new item is added the one at the top is being removed. inline int GetMaxNumEntries() const { return m_nMaxNumEntries; } // --- In : // --- Out : // --- Returns: The the number of the history entries currently displayed in the // control's window. This number cannot exceed the maximum number // of entries currently set for the control (this number can be // retrieved using GetMaxNumEntries() function) // --- Effect: Retrieves the current number of the history entries displayed // in the control's window. inline int GetNumEntries() const { return PtrToInt(m_arrEntries.GetCount()); } // --- In : sFormatString - format string for displaying time stamp // next to a history item (time stamp will be // automatically added to a history entry when // you call AddStampedLine() function). Refer // to COleDateTime::Format() function // documentation for information on how this // format string might look like // --- Out : // --- Returns: // --- Effect: Sets the format string for adding time stamp to history entries // that are being added using AddStampedLine() function. inline void SetTimeStampFormat(CString sFormatString) { m_sDateFormatString=sFormatString; } // --- In : // --- Out : // --- Returns: The format string for displaying time stamp next to a history // item (time stamp will be automatically added to a history entry // when you call AddStampedLine() function). Refer to // COleDateTime::Format() function documentation for information on // how this format string might look like // --- Effect: Retrieves the format string used for adding time stamp to // history entries that are being added using AddStampedLine() // function. inline CString GetTimeStampFormat() const { return m_sDateFormatString; } // --- In : // --- Out : // --- Returns: The height in pixels of history items in the control // --- Effect: Retrieves the height in pixels of history items in the control inline int GetHeight() const { return m_nHeight; } //operations // --- In : string - new line to be added to control as new // history item // bAddToLog - if TRUE this line will be added to the log file // (if any is enabled) // --- Out : // --- Returns: TRUE if new line was successfully added or FALSE otherwise // --- Effect: Adds a new line to the control. If logging is on and the addToLog // param is TRUE then this line is also added to the log file. BOOL AddLine(CString string, BOOL bAddToLog=TRUE); // --- In : string - new line to be added to control as new // history item. This line will be preceded with // time stamp // bAddToLog - if TRUE this line will be added to the log file // (if any is enabled) // --- Out : // --- Returns: TRUE if new time stamped line was successfully added or // FALSE otherwise // --- Effect: Adds a new time stamped line to the control. If logging is on // and the addToLog param is TRUE then this line is also added to // the log file. BOOL AddStampedLine(CString string, BOOL bAddToLog=TRUE); // --- In : string - new text to be added to the last history entry // in the control. // bAddToLog - if TRUE this line will be added to the log file // (if any is enabled) // --- Out : // --- Returns: TRUE if new line was successfully appended or FALSE otherwise // --- Effect: Appends the specified text to the last history entry in the // control. If logging is on and the addToLog param is TRUE then // this line is also added to the log file. BOOL AppendToLine(CString string, BOOL bAddToLog=TRUE); // --- In : // --- Out : // --- Returns: TRUE if the control's contents were removed succesfully or // FALSE otherwise // --- Effect: Clears the internal contents of the control. It doesn't clear the // contents of the log file (if any was enabled) BOOL ClearHistory(); protected: // Returns a string with a time stamp that includes the date. CString GetTimeDateStamp() const; // writes new string in the log file. If bNewLine is set to TRUE '\r\n' will be // added to start new line void WriteToLog(CString string, BOOL bNewLine); // opens up the history log file for writing int OpenLog(); // closes the log file int CloseLog(); // calculates the number of currently visible history entries int GetVisibleCount(); // updates internal settings depending on new font that was set using // SetFont() function void UpdateFontInfo(); // updates scrolling settings whenever the state of the control has changed void UpdateScrollInfo(); // finds the history item with max width (in pixels including offset) void UpdateMaxLengthInfo(); // scrolls the contents to make the last item visible void ScrollToEnd(); // overridden virtual function that prevent COXHistoryCtrl from displaying // default COXScrollWnd context menu virtual BOOL OnPopulateContextMenu(CMenu* pMenu, CPoint& point) { UNREFERENCED_PARAMETER(pMenu); UNREFERENCED_PARAMETER(point); return FALSE; } // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(COXHistoryCtrl) //}}AFX_VIRTUAL public: CString GetTimeStampedFileName(); // --- In : // --- Out : // --- Returns: // --- Effect: Destructs the object virtual ~COXHistoryCtrl(); protected: CString m_sTimeStampedLogFileName; // virtual function is called to initialize the control when it was just // created or subclassed virtual BOOL Initialize(); // Generated message map functions //{{AFX_MSG(COXHistoryCtrl) afx_msg void OnPaint(); afx_msg BOOL OnEraseBkgnd(CDC* pDC); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; #endif