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