| 1 | \section{wxLog classes overview}\label{wxlogoverview} |
| 2 | |
| 3 | Classes: \helpref{wxLog}{wxlog},\\ |
| 4 | \helpref{wxLogStderr}{wxlogstderr},\\ |
| 5 | \helpref{wxLogStream}{wxlogstream},\\ |
| 6 | \helpref{wxLogTextCtrl}{wxlogtextctrl},\\ |
| 7 | \helpref{wxLogWindow}{wxlogwindow},\\ |
| 8 | \helpref{wxLogGui}{wxloggui},\\ |
| 9 | \helpref{wxLogNull}{wxlognull},\\ |
| 10 | \helpref{wxLogChain}{wxlogchain},\\ |
| 11 | \helpref{wxLogPassThrough}{wxlogpassthrough},\\ |
| 12 | \helpref{wxStreamToTextRedirector}{wxstreamtotextredirector} |
| 13 | |
| 14 | This is a general overview of logging classes provided by wxWidgets. The word |
| 15 | logging here has a broad sense, including all of the program output, not only |
| 16 | non-interactive messages. The logging facilities included in wxWidgets provide |
| 17 | the base {\it wxLog} class which defines the standard interface for a {\it log |
| 18 | target} as well as several standard implementations of it and a family of |
| 19 | functions to use with them. |
| 20 | |
| 21 | First of all, no knowledge of {\it wxLog} classes is needed to use them. For |
| 22 | this, you should only know about {\it wxLogXXX()} functions. All of them have |
| 23 | the same syntax as {\it printf()} or {\it vprintf()} , i.e. they take the |
| 24 | format string as the first argument and respectively a variable number of |
| 25 | arguments or a variable argument list pointer. Here are all of them: |
| 26 | |
| 27 | \begin{itemize}\itemsep=0pt |
| 28 | \item{\bf wxLogFatalError} which is like {\it wxLogError}, but also |
| 29 | terminates the program with the exit code $3$ (using {\it abort()} standard |
| 30 | function). Unlike for all the other logging functions, this function can't be |
| 31 | overridden by a log target. |
| 32 | \item{\bf wxLogError} is the function to use for error messages, i.e. the |
| 33 | messages that must be shown to the user. The default processing is to pop up a |
| 34 | message box to inform the user about it. |
| 35 | \item{\bf wxLogWarning} for warnings - they are also normally shown to the |
| 36 | user, but don't interrupt the program work. |
| 37 | \item{\bf wxLogMessage} is for all normal, informational messages. They also |
| 38 | appear in a message box by default (but it can be changed, see below). |
| 39 | \item{\bf wxLogVerbose} is for verbose output. Normally, it is suppressed, but |
| 40 | might be activated if the user wishes to know more details about the program |
| 41 | progress (another, but possibly confusing name for the same function is {\bf |
| 42 | wxLogInfo}). |
| 43 | \item{\bf wxLogStatus} is for status messages - they will go into the status |
| 44 | bar of the active or specified (as the first argument) \helpref{wxFrame}{wxframe} if it has one. |
| 45 | \item{\bf wxLogSysError} is mostly used by wxWidgets itself, but might be |
| 46 | handy for logging errors after system call (API function) failure. It logs the |
| 47 | specified message text as well as the last system error |
| 48 | code ({\it errno} or {\it ::GetLastError()} depending on the platform) and |
| 49 | the corresponding error message. The second form of this function takes the |
| 50 | error code explicitly as the first argument. |
| 51 | \item{\bf wxLogDebug} is {\bf the} right function for debug output. It only |
| 52 | does anything at all in the debug mode (when the preprocessor symbol |
| 53 | \_\_WXDEBUG\_\_ is defined) and expands to nothing in release mode (otherwise). |
| 54 | {\bf Tip:} under Windows, you must either run the program under debugger or |
| 55 | use a 3rd party program such as \urlref{DbgView}{http://www.sysinternals.com} |
| 56 | to actually see the debug output. |
| 57 | \item{\bf wxLogTrace} as {\bf wxLogDebug} only does something in debug |
| 58 | build. The reason for making it a separate function from it is that usually |
| 59 | there are a lot of trace messages, so it might make sense to separate them |
| 60 | from other debug messages which would be flooded in them. Moreover, the second |
| 61 | version of this function takes a trace mask as the first argument which allows |
| 62 | to further restrict the amount of messages generated. |
| 63 | \end{itemize} |
| 64 | |
| 65 | The usage of these functions should be fairly straightforward, however it may |
| 66 | be asked why not use the other logging facilities, such as C standard stdio |
| 67 | functions or C++ streams. The short answer is that they're all very good |
| 68 | generic mechanisms, but are not really adapted for wxWidgets, while the log |
| 69 | classes are. Some of advantages in using wxWidgets log functions are: |
| 70 | |
| 71 | \begin{itemize}\itemsep=0pt |
| 72 | \item{\bf Portability} It is a common practice to use {\it printf()} |
| 73 | statements or cout/cerr C++ streams for writing out some (debug or otherwise) |
| 74 | information. |
| 75 | Although it works just fine under Unix, these messages go strictly nowhere |
| 76 | under Windows where the stdout of GUI programs is not assigned to anything. |
| 77 | Thus, you might view {\it wxLogMessage()} as a simple substitute for {\it |
| 78 | printf()}. |
| 79 | |
| 80 | You can also redirect the {\it wxLogXXX} calls to {\it cout} by just writing: |
| 81 | {\small |
| 82 | \begin{verbatim} |
| 83 | wxLog *logger=new wxLogStream(&cout); |
| 84 | wxLog::SetActiveTarget(logger); |
| 85 | \end{verbatim} |
| 86 | } |
| 87 | |
| 88 | Finally, there is also a possibility to redirect the output sent to {\it cout} |
| 89 | to a \helpref{wxTextCtrl}{wxtextctrl} by using the |
| 90 | \helpref{wxStreamToTextRedirector}{wxstreamtotextredirector} class. |
| 91 | \item{\bf Flexibility} The output of wxLog functions can be redirected or |
| 92 | suppressed entirely based on their importance, which is either impossible or |
| 93 | difficult to do with traditional methods. For example, only error messages, or |
| 94 | only error messages and warnings might be logged, filtering out all |
| 95 | informational messages. |
| 96 | \item{\bf Completeness} Usually, an error message should be presented to the user |
| 97 | when some operation fails. Let's take a quite simple but common case of a file |
| 98 | error: suppose that you're writing your data file on disk and there is not |
| 99 | enough space. The actual error might have been detected inside wxWidgets code |
| 100 | (say, in {\it wxFile::Write}), so the calling function doesn't really know the |
| 101 | exact reason of the failure, it only knows that the data file couldn't be |
| 102 | written to the disk. However, as wxWidgets uses {\it wxLogError()} in this |
| 103 | situation, the exact error code (and the corresponding error message) will be |
| 104 | given to the user together with "high level" message about data file writing |
| 105 | error. |
| 106 | \end{itemize} |
| 107 | |
| 108 | After having enumerated all the functions which are normally used to log the |
| 109 | messages, and why would you want to use them we now describe how all this |
| 110 | works. |
| 111 | |
| 112 | wxWidgets has the notion of a {\it log target}: it is just a class deriving |
| 113 | from \helpref{wxLog}{wxlog}. As such, it implements the virtual functions of |
| 114 | the base class which are called when a message is logged. Only one log target |
| 115 | is {\it active} at any moment, this is the one used by {\it wxLogXXX()} |
| 116 | functions. The normal usage of a log object (i.e. object of a class derived |
| 117 | from wxLog) is to install it as the active target with a call to {\it |
| 118 | SetActiveTarget()} and it will be used automatically by all subsequent calls |
| 119 | to {\it wxLogXXX()} functions. |
| 120 | |
| 121 | To create a new log target class you only need to derive it from wxLog and |
| 122 | implement one (or both) of {\it DoLog()} and {\it DoLogString()} in it. The |
| 123 | second one is enough if you're happy with the standard wxLog message |
| 124 | formatting (prepending "Error:" or "Warning:", timestamping \&c) but just want |
| 125 | to send the messages somewhere else. The first one may be overridden to do |
| 126 | whatever you want but you have to distinguish between the different message |
| 127 | types yourself. |
| 128 | |
| 129 | There are some predefined classes deriving from wxLog and which might be |
| 130 | helpful to see how you can create a new log target class and, of course, may |
| 131 | also be used without any change. There are: |
| 132 | |
| 133 | \begin{itemize}\itemsep=0pt |
| 134 | \item{\bf wxLogStderr} This class logs messages to a {\it FILE *}, using |
| 135 | stderr by default as its name suggests. |
| 136 | \item{\bf wxLogStream} This class has the same functionality as wxLogStderr, |
| 137 | but uses {\it ostream} and cerr instead of {\it FILE *} and stderr. |
| 138 | \item{\bf wxLogGui} This is the standard log target for wxWidgets |
| 139 | applications (it is used by default if you don't do anything) and provides the |
| 140 | most reasonable handling of all types of messages for given platform. |
| 141 | \item{\bf wxLogWindow} This log target provides a "log console" which |
| 142 | collects all messages generated by the application and also passes them to the |
| 143 | previous active log target. The log window frame has a menu allowing user to |
| 144 | clear the log, close it completely or save all messages to file. |
| 145 | \item{\bf wxLogNull} The last log class is quite particular: it doesn't do |
| 146 | anything. The objects of this class may be instantiated to (temporarily) |
| 147 | suppress output of {\it wxLogXXX()} functions. As an example, trying to open a |
| 148 | non-existing file will usually provoke an error message, but if for some |
| 149 | reasons it is unwanted, just use this construction: |
| 150 | |
| 151 | {\small% |
| 152 | \begin{verbatim} |
| 153 | wxFile file; |
| 154 | |
| 155 | // wxFile.Open() normally complains if file can't be opened, we don't want it |
| 156 | { |
| 157 | wxLogNull logNo; |
| 158 | if ( !file.Open("bar") ) |
| 159 | ... process error ourselves ... |
| 160 | } // ~wxLogNull called, old log sink restored |
| 161 | |
| 162 | wxLogMessage("..."); // ok |
| 163 | \end{verbatim} |
| 164 | }% |
| 165 | \end{itemize} |
| 166 | |
| 167 | The log targets can also be combined: for example you may wish to redirect the |
| 168 | messages somewhere else (for example, to a log file) but also process them as |
| 169 | normally. For this the \helpref{wxLogChain}{wxlogchain} and |
| 170 | \helpref{wxLogPassThrough}{wxlogpassthrough} can be used. |
| 171 | |