home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / include / wx / log.h < prev    next >
C/C++ Source or Header  |  2003-01-03  |  24KB  |  621 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        wx/log.h
  3. // Purpose:     Assorted wxLogXXX functions, and wxLog (sink for logs)
  4. // Author:      Vadim Zeitlin
  5. // Modified by:
  6. // Created:     29/01/98
  7. // RCS-ID:      $Id: log.h,v 1.72.2.2 2003/01/01 22:49:06 RD Exp $
  8. // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
  9. // Licence:     wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifndef   _WX_LOG_H_
  13. #define   _WX_LOG_H_
  14.  
  15. #if defined(__GNUG__) && !defined(__APPLE__)
  16.     #pragma interface "log.h"
  17. #endif
  18.  
  19. #include "wx/setup.h"
  20. #include "wx/string.h"
  21.  
  22. // ----------------------------------------------------------------------------
  23. // forward declarations
  24. // ----------------------------------------------------------------------------
  25.  
  26. class WXDLLEXPORT wxTextCtrl;
  27. class WXDLLEXPORT wxLogFrame;
  28. class WXDLLEXPORT wxFrame;
  29.  
  30. // ----------------------------------------------------------------------------
  31. // types
  32. // ----------------------------------------------------------------------------
  33.  
  34. typedef unsigned long wxTraceMask;
  35. typedef unsigned long wxLogLevel;
  36.  
  37. // ----------------------------------------------------------------------------
  38. // headers
  39. // ----------------------------------------------------------------------------
  40.  
  41. #if wxUSE_LOG
  42.  
  43. #include <time.h>   // for time_t
  44.  
  45. #include "wx/dynarray.h"
  46.  
  47. #ifndef wxUSE_LOG_DEBUG
  48. #  ifdef __WXDEBUG__
  49. #    define wxUSE_LOG_DEBUG 1
  50. #  else // !__WXDEBUG__
  51. #    define wxUSE_LOG_DEBUG 0
  52. #  endif
  53. #endif
  54.  
  55. // ----------------------------------------------------------------------------
  56. // constants
  57. // ----------------------------------------------------------------------------
  58.  
  59. // different standard log levels (you may also define your own)
  60. enum
  61. {
  62.     wxLOG_FatalError, // program can't continue, abort immediately
  63.     wxLOG_Error,      // a serious error, user must be informed about it
  64.     wxLOG_Warning,    // user is normally informed about it but may be ignored
  65.     wxLOG_Message,    // normal message (i.e. normal output of a non GUI app)
  66.     wxLOG_Status,     // informational: might go to the status line of GUI app
  67.     wxLOG_Info,       // informational message (a.k.a. 'Verbose')
  68.     wxLOG_Debug,      // never shown to the user, disabled in release mode
  69.     wxLOG_Trace,      // trace messages are also only enabled in debug mode
  70.     wxLOG_Progress,   // used for progress indicator (not yet)
  71.     wxLOG_User = 100, // user defined levels start here
  72.     wxLOG_Max = 10000
  73. };
  74.  
  75. // symbolic trace masks - wxLogTrace("foo", "some trace message...") will be
  76. // discarded unless the string "foo" has been added to the list of allowed
  77. // ones with AddTraceMask()
  78.  
  79. #define wxTRACE_MemAlloc wxT("memalloc") // trace memory allocation (new/delete)
  80. #define wxTRACE_Messages wxT("messages") // trace window messages/X callbacks
  81. #define wxTRACE_ResAlloc wxT("resalloc") // trace GDI resource allocation
  82. #define wxTRACE_RefCount wxT("refcount") // trace various ref counting operations
  83.  
  84. #ifdef  __WXMSW__
  85.     #define wxTRACE_OleCalls wxT("ole")  // OLE interface calls
  86. #endif
  87.  
  88. // the trace masks have been superceded by symbolic trace constants, they're
  89. // for compatibility only andwill be removed soon - do NOT use them
  90.  
  91. // meaning of different bits of the trace mask (which allows selectively
  92. // enable/disable some trace messages)
  93. #define wxTraceMemAlloc 0x0001  // trace memory allocation (new/delete)
  94. #define wxTraceMessages 0x0002  // trace window messages/X callbacks
  95. #define wxTraceResAlloc 0x0004  // trace GDI resource allocation
  96. #define wxTraceRefCount 0x0008  // trace various ref counting operations
  97.  
  98. #ifdef  __WXMSW__
  99.     #define wxTraceOleCalls 0x0100  // OLE interface calls
  100. #endif
  101.  
  102. #include "wx/ioswrap.h"
  103.  
  104. // ----------------------------------------------------------------------------
  105. // derive from this class to redirect (or suppress, or ...) log messages
  106. // normally, only a single instance of this class exists but it's not enforced
  107. // ----------------------------------------------------------------------------
  108.  
  109. class WXDLLEXPORT wxLog
  110. {
  111. public:
  112.     // ctor
  113.     wxLog();
  114.  
  115.     // Internal buffer.
  116.         // Allow replacement of the fixed size static buffer with
  117.         // a user allocated one.  Pass in NULL to restore the
  118.         // built in static buffer.
  119.     static wxChar *SetLogBuffer( wxChar *buf, size_t size = 0 );
  120.  
  121.     // these functions allow to completely disable all log messages
  122.         // is logging disabled now?
  123.     static bool IsEnabled() { return ms_doLog; }
  124.         // change the flag state, return the previous one
  125.     static bool EnableLogging(bool doIt = TRUE)
  126.         { bool doLogOld = ms_doLog; ms_doLog = doIt; return doLogOld; }
  127.  
  128.     // static sink function - see DoLog() for function to overload in the
  129.     // derived classes
  130.     static void OnLog(wxLogLevel level, const wxChar *szString, time_t t)
  131.     {
  132.         if ( IsEnabled() && ms_logLevel >= level ) {
  133.             wxLog *pLogger = GetActiveTarget();
  134.             if ( pLogger )
  135.                 pLogger->DoLog(level, szString, t);
  136.         }
  137.     }
  138.  
  139.     // message buffering
  140.         // flush shows all messages if they're not logged immediately (FILE
  141.         // and iostream logs don't need it, but wxGuiLog does to avoid showing
  142.         // 17 modal dialogs one after another)
  143.     virtual void Flush();
  144.         // call to Flush() may be optimized: call it only if this function
  145.         // returns true (although Flush() also returns immediately if there is
  146.         // no messages, this functions is more efficient because inline)
  147.     bool HasPendingMessages() const { return m_bHasMessages; }
  148.  
  149.     // only one sink is active at each moment
  150.         // flush the active target if any
  151.     static void FlushActive()
  152.     {
  153.         if ( !ms_suspendCount )
  154.         {
  155.             wxLog *log = GetActiveTarget();
  156.             if ( log && log->HasPendingMessages() )
  157.                 log->Flush();
  158.         }
  159.     }
  160.         // get current log target, will call wxApp::CreateLogTarget() to
  161.         // create one if none exists
  162.     static wxLog *GetActiveTarget();
  163.         // change log target, pLogger may be NULL
  164.     static wxLog *SetActiveTarget(wxLog *pLogger);
  165.  
  166.         // suspend the message flushing of the main target until the next call
  167.         // to Resume() - this is mainly for internal use (to prevent wxYield()
  168.         // from flashing the messages)
  169.     static void Suspend() { ms_suspendCount++; }
  170.         // must be called for each Suspend()!
  171.     static void Resume() { ms_suspendCount--; }
  172.  
  173.     // functions controlling the default wxLog behaviour
  174.         // verbose mode is activated by standard command-line '-verbose'
  175.         // option
  176.     static void SetVerbose(bool bVerbose = TRUE) { ms_bVerbose = bVerbose; }
  177.  
  178.         // Set log level.  Log messages with level > logLevel will not be logged.
  179.     static void SetLogLevel(wxLogLevel logLevel) { ms_logLevel = logLevel; }
  180.  
  181.         // should GetActiveTarget() try to create a new log object if the
  182.         // current is NULL?
  183.     static void DontCreateOnDemand();
  184.  
  185.         // trace mask (see wxTraceXXX constants for details)
  186.     static void SetTraceMask(wxTraceMask ulMask) { ms_ulTraceMask = ulMask; }
  187.         // add string trace mask
  188.     static void AddTraceMask(const wxString& str) { ms_aTraceMasks.Add(str); }
  189.         // add string trace mask
  190.     static void RemoveTraceMask(const wxString& str);
  191.         // remove all string trace masks
  192.     static void ClearTraceMasks();
  193.         // get string trace masks
  194.     static const wxArrayString &GetTraceMasks() { return ms_aTraceMasks; }
  195.  
  196.         // sets the timestamp string: this is used as strftime() format string
  197.         // for the log targets which add time stamps to the messages - set it
  198.         // to NULL to disable time stamping completely.
  199.     static void SetTimestamp(const wxChar *ts) { ms_timestamp = ts; }
  200.  
  201.  
  202.     // accessors
  203.         // gets the verbose status
  204.     static bool GetVerbose() { return ms_bVerbose; }
  205.         // get trace mask
  206.     static wxTraceMask GetTraceMask() { return ms_ulTraceMask; }
  207.         // is this trace mask in the list?
  208.     static bool IsAllowedTraceMask(const wxChar *mask)
  209.         { return ms_aTraceMasks.Index(mask) != wxNOT_FOUND; }
  210.         // return the current loglevel limit
  211.     static wxLogLevel GetLogLevel() { return ms_logLevel; }
  212.  
  213.         // get the current timestamp format string (may be NULL)
  214.     static const wxChar *GetTimestamp() { return ms_timestamp; }
  215.  
  216.  
  217.     // helpers
  218.         // put the time stamp into the string if ms_timestamp != NULL (don't
  219.         // change it otherwise)
  220.     static void TimeStamp(wxString *str);
  221.  
  222.     // make dtor virtual for all derived classes
  223.     virtual ~wxLog() { }
  224.  
  225. protected:
  226.     bool m_bHasMessages; // any messages in the queue?
  227.  
  228.     // the logging functions that can be overriden
  229.         // default DoLog() prepends the time stamp and a prefix corresponding
  230.         // to the message to szString and then passes it to DoLogString()
  231.     virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
  232.         // default DoLogString does nothing but is not pure virtual because if
  233.         // you override DoLog() you might not need it at all
  234.     virtual void DoLogString(const wxChar *szString, time_t t);
  235.  
  236. private:
  237.     // static variables
  238.     // ----------------
  239.  
  240.     static wxLog      *ms_pLogger;      // currently active log sink
  241.     static bool        ms_doLog;        // FALSE => all logging disabled
  242.     static bool        ms_bAutoCreate;  // create new log targets on demand?
  243.     static bool        ms_bVerbose;     // FALSE => ignore LogInfo messages
  244.  
  245.     static wxLogLevel  ms_logLevel;     // limit logging to levels <= ms_logLevel
  246.  
  247.     static size_t      ms_suspendCount; // if positive, logs are not flushed
  248.  
  249.     // format string for strftime(), if NULL, time stamping log messages is
  250.     // disabled
  251.     static const wxChar *ms_timestamp;
  252.  
  253.     static wxTraceMask ms_ulTraceMask;   // controls wxLogTrace behaviour
  254.     static wxArrayString ms_aTraceMasks; // more powerful filter for wxLogTrace
  255. };
  256.  
  257. // ----------------------------------------------------------------------------
  258. // "trivial" derivations of wxLog
  259. // ----------------------------------------------------------------------------
  260.  
  261. // log everything to a "FILE *", stderr by default
  262. class WXDLLEXPORT wxLogStderr : public wxLog
  263. {
  264.     DECLARE_NO_COPY_CLASS(wxLogStderr)
  265.  
  266. public:
  267.     // redirect log output to a FILE
  268.     wxLogStderr(FILE *fp = (FILE *) NULL);
  269.  
  270. protected:
  271.     // implement sink function
  272.     virtual void DoLogString(const wxChar *szString, time_t t);
  273.  
  274.     FILE *m_fp;
  275. };
  276.  
  277. #if wxUSE_STD_IOSTREAM
  278.  
  279. // log everything to an "ostream", cerr by default
  280. class WXDLLEXPORT wxLogStream : public wxLog
  281. {
  282. public:
  283.     // redirect log output to an ostream
  284.     wxLogStream(wxSTD ostream *ostr = (wxSTD ostream *) NULL);
  285.  
  286. protected:
  287.     // implement sink function
  288.     virtual void DoLogString(const wxChar *szString, time_t t);
  289.  
  290.     // using ptr here to avoid including <iostream.h> from this file
  291.     wxSTD ostream *m_ostr;
  292. };
  293.  
  294. #endif // wxUSE_STD_IOSTREAM
  295.  
  296. // ----------------------------------------------------------------------------
  297. // /dev/null log target: suppress logging until this object goes out of scope
  298. // ----------------------------------------------------------------------------
  299.  
  300. // example of usage:
  301. /*
  302.     void Foo()
  303.     {
  304.         wxFile file;
  305.  
  306.         // wxFile.Open() normally complains if file can't be opened, we don't
  307.         // want it
  308.         wxLogNull logNo;
  309.  
  310.         if ( !file.Open("bar") )
  311.             ... process error ourselves ...
  312.  
  313.         // ~wxLogNull called, old log sink restored
  314.     }
  315.  */
  316. class WXDLLEXPORT wxLogNull
  317. {
  318. public:
  319.     wxLogNull() : m_flagOld(wxLog::EnableLogging(FALSE)) { }
  320.     ~wxLogNull() { (void)wxLog::EnableLogging(m_flagOld); }
  321.  
  322. private:
  323.     bool m_flagOld; // the previous value of the wxLog::ms_doLog
  324. };
  325.  
  326. // ----------------------------------------------------------------------------
  327. // chaining log target: installs itself as a log target and passes all
  328. // messages to the real log target given to it in the ctor but also forwards
  329. // them to the previously active one
  330. //
  331. // note that you don't have to call SetActiveTarget() with this class, it
  332. // does it itself in its ctor
  333. // ----------------------------------------------------------------------------
  334.  
  335. class WXDLLEXPORT wxLogChain : public wxLog
  336. {
  337. public:
  338.     wxLogChain(wxLog *logger);
  339.     virtual ~wxLogChain();
  340.  
  341.     // change the new log target
  342.     void SetLog(wxLog *logger);
  343.  
  344.     // this can be used to temporarily disable (and then reenable) passing
  345.     // messages to the old logger (by default we do pass them)
  346.     void PassMessages(bool bDoPass) { m_bPassMessages = bDoPass; }
  347.  
  348.     // are we passing the messages to the previous log target?
  349.     bool IsPassingMessages() const { return m_bPassMessages; }
  350.  
  351.     // return the previous log target (may be NULL)
  352.     wxLog *GetOldLog() const { return m_logOld; }
  353.  
  354.     // override base class version to flush the old logger as well
  355.     virtual void Flush();
  356.  
  357. protected:
  358.     // pass the chain to the old logger if needed
  359.     virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
  360.  
  361. private:
  362.     // the current log target
  363.     wxLog *m_logNew;
  364.  
  365.     // the previous log target
  366.     wxLog *m_logOld;
  367.  
  368.     // do we pass the messages to the old logger?
  369.     bool m_bPassMessages;
  370. };
  371.  
  372. // a chain log target which uses itself as the new logger
  373. class WXDLLEXPORT wxLogPassThrough : public wxLogChain
  374. {
  375. public:
  376.     wxLogPassThrough();
  377. };
  378.  
  379. // ----------------------------------------------------------------------------
  380. // the following log targets are only compiled in if the we're compiling the
  381. // GUI part (andnot just the base one) of the library, they're implemented in
  382. // src/generic/logg.cpp *and not src/common/log.cpp unlike all the rest)
  383. // ----------------------------------------------------------------------------
  384.  
  385. #if wxUSE_GUI
  386.  
  387. #if wxUSE_TEXTCTRL
  388.  
  389. // log everything to a text window (GUI only of course)
  390. class WXDLLEXPORT wxLogTextCtrl : public wxLog
  391. {
  392. public:
  393.     wxLogTextCtrl(wxTextCtrl *pTextCtrl);
  394.  
  395. private:
  396.     // implement sink function
  397.     virtual void DoLogString(const wxChar *szString, time_t t);
  398.  
  399.     // the control we use
  400.     wxTextCtrl *m_pTextCtrl;
  401. };
  402.  
  403. #endif // wxUSE_TEXTCTRL
  404.  
  405. // ----------------------------------------------------------------------------
  406. // GUI log target, the default one for wxWindows programs
  407. // ----------------------------------------------------------------------------
  408.  
  409. #if wxUSE_LOGGUI
  410.  
  411. class WXDLLEXPORT wxLogGui : public wxLog
  412. {
  413. public:
  414.     // ctor
  415.     wxLogGui();
  416.  
  417.     // show all messages that were logged since the last Flush()
  418.     virtual void Flush();
  419.  
  420. protected:
  421.     virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
  422.  
  423.     // empty everything
  424.     void Clear();
  425.  
  426.     wxArrayString m_aMessages;      // the log message texts
  427.     wxArrayInt    m_aSeverity;      // one of wxLOG_XXX values
  428.     wxArrayLong   m_aTimes;         // the time of each message
  429.     bool          m_bErrors,        // do we have any errors?
  430.                   m_bWarnings;      // any warnings?
  431. };
  432.  
  433. #endif // wxUSE_LOGGUI
  434.  
  435. // ----------------------------------------------------------------------------
  436. // (background) log window: this class forwards all log messages to the log
  437. // target which was active when it was instantiated, but also collects them
  438. // to the log window. This window has it's own menu which allows the user to
  439. // close it, clear the log contents or save it to the file.
  440. // ----------------------------------------------------------------------------
  441.  
  442. #if wxUSE_LOGWINDOW
  443.  
  444. class WXDLLEXPORT wxLogWindow : public wxLogPassThrough
  445. {
  446. public:
  447.     wxLogWindow(wxFrame *pParent,         // the parent frame (can be NULL)
  448.                 const wxChar *szTitle,    // the title of the frame
  449.                 bool bShow = TRUE,        // show window immediately?
  450.                 bool bPassToOld = TRUE);  // pass messages to the old target?
  451.  
  452.     ~wxLogWindow();
  453.  
  454.     // window operations
  455.         // show/hide the log window
  456.     void Show(bool bShow = TRUE);
  457.         // retrieve the pointer to the frame
  458.     wxFrame *GetFrame() const;
  459.  
  460.     // overridables
  461.         // called immediately after the log frame creation allowing for
  462.         // any extra initializations
  463.     virtual void OnFrameCreate(wxFrame *frame);
  464.         // called if the user closes the window interactively, will not be
  465.         // called if it is destroyed for another reason (such as when program
  466.         // exits) - return TRUE from here to allow the frame to close, FALSE
  467.         // to prevent this from happening
  468.     virtual bool OnFrameClose(wxFrame *frame);
  469.         // called right before the log frame is going to be deleted: will
  470.         // always be called unlike OnFrameClose()
  471.     virtual void OnFrameDelete(wxFrame *frame);
  472.  
  473. protected:
  474.     virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
  475.     virtual void DoLogString(const wxChar *szString, time_t t);
  476.  
  477. private:
  478.     wxLogFrame *m_pLogFrame;      // the log frame
  479. };
  480.  
  481. #endif // wxUSE_LOGWINDOW
  482.  
  483. #endif // wxUSE_GUI
  484.  
  485. // ============================================================================
  486. // global functions
  487. // ============================================================================
  488.  
  489. // ----------------------------------------------------------------------------
  490. // Log functions should be used by application instead of stdio, iostream &c
  491. // for log messages for easy redirection
  492. // ----------------------------------------------------------------------------
  493.  
  494. // ----------------------------------------------------------------------------
  495. // get error code/error message from system in a portable way
  496. // ----------------------------------------------------------------------------
  497.  
  498. // return the last system error code
  499. WXDLLEXPORT unsigned long wxSysErrorCode();
  500.  
  501. // return the error message for given (or last if 0) error code
  502. WXDLLEXPORT const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
  503.  
  504. // ----------------------------------------------------------------------------
  505. // define wxLog<level>
  506. // ----------------------------------------------------------------------------
  507.  
  508. #define DECLARE_LOG_FUNCTION(level)                                 \
  509. extern void WXDLLEXPORT wxVLog##level(const wxChar *szFormat,       \
  510.                                       va_list argptr);              \
  511. extern void WXDLLEXPORT wxLog##level(const wxChar *szFormat,        \
  512.                                      ...) ATTRIBUTE_PRINTF_1
  513. #define DECLARE_LOG_FUNCTION2(level, arg1)                          \
  514. extern void WXDLLEXPORT wxVLog##level(arg1, const wxChar *szFormat, \
  515.                                       va_list argptr);              \
  516. extern void WXDLLEXPORT wxLog##level(arg1, const wxChar *szFormat,  \
  517.                                      ...) ATTRIBUTE_PRINTF_2
  518.  
  519. #else // !wxUSE_LOG
  520.  
  521. // log functions do nothing at all
  522. #define DECLARE_LOG_FUNCTION(level)                                 \
  523. inline void WXDLLEXPORT wxVLog##level(const wxChar *szFormat,       \
  524.                                      va_list argptr) {}             \
  525. inline void WXDLLEXPORT wxLog##level(const wxChar *szFormat, ...) {}
  526. #define DECLARE_LOG_FUNCTION2(level, arg1)                          \
  527. inline void WXDLLEXPORT wxVLog##level(arg1, const wxChar *szFormat, \
  528.                                      va_list argptr) {}             \
  529. inline void WXDLLEXPORT wxLog##level(arg1, const wxChar *szFormat, ...) {}
  530.  
  531. #endif // wxUSE_LOG/!wxUSE_LOG
  532.  
  533. // a generic function for all levels (level is passes as parameter)
  534. DECLARE_LOG_FUNCTION2(Generic, wxLogLevel level);
  535.  
  536. // one function per each level
  537. DECLARE_LOG_FUNCTION(FatalError);
  538. DECLARE_LOG_FUNCTION(Error);
  539. DECLARE_LOG_FUNCTION(Warning);
  540. DECLARE_LOG_FUNCTION(Message);
  541. DECLARE_LOG_FUNCTION(Info);
  542. DECLARE_LOG_FUNCTION(Verbose);
  543.  
  544. // this function sends the log message to the status line of the top level
  545. // application frame, if any
  546. DECLARE_LOG_FUNCTION(Status);
  547.  
  548. // this one is the same as previous except that it allows to explicitly
  549. // specify the frame to which the output should go
  550. DECLARE_LOG_FUNCTION2(Status, wxFrame *pFrame);
  551.  
  552. // additional one: as wxLogError, but also logs last system call error code
  553. // and the corresponding error message if available
  554. DECLARE_LOG_FUNCTION(SysError);
  555.  
  556. // and another one which also takes the error code (for those broken APIs
  557. // that don't set the errno (like registry APIs in Win32))
  558. DECLARE_LOG_FUNCTION2(SysError, long lErrCode);
  559.  
  560. // debug functions do nothing in release mode
  561. #if wxUSE_LOG_DEBUG
  562.     DECLARE_LOG_FUNCTION(Debug);
  563.  
  564.     // first kind of LogTrace is unconditional: it doesn't check the level,
  565.     DECLARE_LOG_FUNCTION(Trace);
  566.  
  567.     // this second version will only log the message if the mask had been
  568.     // added to the list of masks with AddTraceMask()
  569.     DECLARE_LOG_FUNCTION2(Trace, const wxChar *mask);
  570.  
  571.     // the last one does nothing if all of level bits are not set
  572.     // in wxLog::GetActive()->GetTraceMask() - it's deprecated in favour of
  573.     // string identifiers
  574.     DECLARE_LOG_FUNCTION2(Trace, wxTraceMask mask);
  575. #else   //!debug
  576.     // these functions do nothing in release builds
  577.     inline void wxVLogDebug(const wxChar *, va_list) { }
  578.     inline void wxLogDebug(const wxChar *, ...) { }
  579.     inline void wxVLogTrace(const wxChar *, va_list) { }
  580.     inline void wxLogTrace(const wxChar *, ...) { }
  581.     inline void wxVLogTrace(wxTraceMask, const wxChar *, va_list) { }
  582.     inline void wxLogTrace(wxTraceMask, const wxChar *, ...) { }
  583.     inline void wxVLogTrace(const wxChar *, const wxChar *, va_list) { }
  584.     inline void wxLogTrace(const wxChar *, const wxChar *, ...) { }
  585. #endif // debug/!debug
  586.  
  587. // wxLogFatalError helper: show the (fatal) error to the user in a safe way,
  588. // i.e. without using wxMessageBox() for example because it could crash
  589. void WXDLLEXPORT wxSafeShowMessage(const wxString& title, const wxString& text);
  590.  
  591. // ----------------------------------------------------------------------------
  592. // debug only logging functions: use them with API name and error code
  593. // ----------------------------------------------------------------------------
  594.  
  595. #ifdef __WXDEBUG__
  596.     // make life easier for people using VC++ IDE: clicking on the message
  597.     // will take us immediately to the place of the failed API
  598. #ifdef __VISUALC__
  599.     #define wxLogApiError(api, rc)                                            \
  600.         wxLogDebug(wxT("%s(%d): '%s' failed with error 0x%08lx (%s)."),       \
  601.                    __TFILE__, __LINE__, api,                                  \
  602.                    (long)rc, wxSysErrorMsg(rc))
  603. #else // !VC++
  604.     #define wxLogApiError(api, rc)                                            \
  605.         wxLogDebug(wxT("In file %s at line %d: '%s' failed with "             \
  606.                        "error 0x%08lx (%s)."),                                \
  607.                    __TFILE__, __LINE__, api,                                  \
  608.                    (long)rc, wxSysErrorMsg(rc))
  609. #endif // VC++/!VC++
  610.  
  611.     #define wxLogLastError(api) wxLogApiError(api, wxSysErrorCode())
  612.  
  613. #else   //!debug
  614.     inline void wxLogApiError(const wxChar *, long) { }
  615.     inline void wxLogLastError(const wxChar *) { }
  616. #endif  //debug/!debug
  617.  
  618. #endif  // _WX_LOG_H_
  619.  
  620. // vi:sts=4:sw=4:et
  621.