\membersection{wxLog::OnLog}\label{wxlogonlog}
 
-\func{static void}{OnLog}{\param{wxLogLevel }{ level}, \param{const char * }{ message}}
+\func{static void}{OnLog}{\param{wxLogLevel }{ level}, \param{const wxString\& }{ message}}
 
 Forwards the message at specified level to the {\it DoLog()} function of the
 active log target if there is any, does nothing otherwise.
 
 \membersection{wxLog::DoLog}\label{wxlogdolog}
 
-\func{virtual void}{DoLog}{\param{wxLogLevel }{level}, \param{const wxChar }{*msg}, \param{time\_t }{timestamp}}
+\func{virtual void}{DoLog}{\param{wxLogLevel }{level}, \param{const wxString\& }{msg}, \param{time\_t }{timestamp}}
 
 Called to process the message of the specified severity. {\it msg} is the text
 of the message as specified in the call of {\it wxLogXXX()} function which
 
 \membersection{wxLog::DoLogString}\label{wxlogdologstring}
 
-\func{virtual void}{DoLogString}{\param{const wxChar }{*msg}, \param{time\_t }{timestamp}}
+\func{virtual void}{DoLogString}{\param{const wxString\& }{msg}, \param{time\_t }{timestamp}}
 
 Called to log the specified string. The timestamp is already included in the
 string but still passed to this function.
 
 \membersection{wxLog::IsAllowedTraceMask}\label{wxlogisallowedtracemask}
 
-\func{static bool}{IsAllowedTraceMask}{\param{const wxChar *}{mask}}
+\func{static bool}{IsAllowedTraceMask}{\param{const wxString\& }{mask}}
 
 Returns true if the {\it mask} is one of allowed masks for
 \helpref{wxLogTrace}{wxlogtrace}.
 
 
 protected:
     // implement sink function
-    virtual void DoLogString(const wxChar *szString, time_t t);
+    virtual void DoLogString(const wxString& szString, time_t t);
 
 private:
     // the control we use
     virtual void Flush();
 
 protected:
-    virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
+    virtual void DoLog(wxLogLevel level, const wxString& szString, time_t t);
 
     // empty everything
     void Clear();
     virtual void OnFrameDelete(wxFrame *frame);
 
 protected:
-    virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
-    virtual void DoLogString(const wxChar *szString, time_t t);
+    virtual void DoLog(wxLogLevel level, const wxString& szString, time_t t);
+    virtual void DoLogString(const wxString& szString, time_t t);
 
 private:
     wxLogFrame *m_pLogFrame;      // the log frame
 
 
     // static sink function - see DoLog() for function to overload in the
     // derived classes
-    static void OnLog(wxLogLevel level, const wxChar *szString, time_t t);
+    static void OnLog(wxLogLevel level, const wxString& szString, time_t t);
 
     // message buffering
 
     static wxTraceMask GetTraceMask() { return ms_ulTraceMask; }
 
     // is this trace mask in the list?
-    static bool IsAllowedTraceMask(const wxChar *mask);
+    static bool IsAllowedTraceMask(const wxString& mask);
 
     // return the current loglevel limit
     static wxLogLevel GetLogLevel() { return ms_logLevel; }
 
     // default DoLog() prepends the time stamp and a prefix corresponding
     // to the message to szString and then passes it to DoLogString()
-    virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
+    virtual void DoLog(wxLogLevel level, const wxString& szString, time_t t);
+#if WXWIN_COMPATIBILITY_2_8
+    // these shouldn't be used by new code
+    virtual void DoLog(wxLogLevel WXUNUSED(level),
+                       const char *WXUNUSED(szString), time_t WXUNUSED(t)) {}
+    virtual void DoLog(wxLogLevel WXUNUSED(level),
+                       const wchar_t *WXUNUSED(szString), time_t WXUNUSED(t)) {}
+#endif
+
+    void LogString(const wxString& szString, time_t t)
+        { DoLogString(szString, t); }
 
     // default DoLogString does nothing but is not pure virtual because if
     // you override DoLog() you might not need it at all
-    virtual void DoLogString(const wxChar *szString, time_t t);
+    virtual void DoLogString(const wxString& szString, time_t t);
+#if WXWIN_COMPATIBILITY_2_8
+    // these shouldn't be used by new code
+    virtual void DoLogString(const char *WXUNUSED(szString),
+                             time_t WXUNUSED(t)) {}
+    virtual void DoLogString(const wchar_t *WXUNUSED(szString),
+                             time_t WXUNUSED(t)) {}
+#endif
 
     // log a line containing the number of times the previous message was
     // repeated
     virtual void Flush();
 
 protected:
-    virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
-    virtual void DoLogString(const wxChar *szString, time_t t);
+    virtual void DoLog(wxLogLevel level, const wxString& szString, time_t t);
+    virtual void DoLogString(const wxString& szString, time_t t);
 
 private:
     wxString m_str;
 
 protected:
     // implement sink function
-    virtual void DoLogString(const wxChar *szString, time_t t);
+    virtual void DoLogString(const wxString& szString, time_t t);
 
     FILE *m_fp;
 
 
 protected:
     // implement sink function
-    virtual void DoLogString(const wxChar *szString, time_t t);
+    virtual void DoLogString(const wxString& szString, time_t t);
 
     // using ptr here to avoid including <iostream.h> from this file
     wxSTD ostream *m_ostr;
 
 protected:
     // pass the chain to the old logger if needed
-    virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
+    virtual void DoLog(wxLogLevel level, const wxString& szString, time_t t);
 
 private:
     // the current log target
 
 #endif
         ms_prevCounter = 0;
         ms_prevString.clear();
-        pLogger->DoLog(ms_prevLevel, msg.c_str(), ms_prevTimeStamp);
+        pLogger->DoLog(ms_prevLevel, msg, ms_prevTimeStamp);
     }
     return retval;
 }
 }
 
 /* static */
-void wxLog::OnLog(wxLogLevel level, const wxChar *szString, time_t t)
+void wxLog::OnLog(wxLogLevel level, const wxString& szString, time_t t)
 {
     if ( IsEnabled() && ms_logLevel >= level )
     {
 #endif // wxUSE_DATETIME
 }
 
-void wxLog::DoLog(wxLogLevel level, const wxChar *szString, time_t t)
+void wxLog::DoLog(wxLogLevel level, const wxString& szString, time_t t)
 {
+#if WXWIN_COMPATIBILITY_2_8
+    // DoLog() signature changed since 2.8, so we call the old versions here
+    // so that existing custom log classes still work:
+    DoLog(level, (const char*)szString.mb_str(), t);
+    DoLog(level, (const wchar_t*)szString.wc_str(), t);
+#endif
+
     switch ( level ) {
         case wxLOG_FatalError:
-            DoLogString(wxString(_("Fatal error: ")) + szString, t);
-            DoLogString(_("Program aborted."), t);
+            LogString(_("Fatal error: ") + szString, t);
+            LogString(_("Program aborted."), t);
             Flush();
 #ifdef __WXWINCE__
             ExitThread(3);
             break;
 
         case wxLOG_Error:
-            DoLogString(wxString(_("Error: ")) + szString, t);
+            LogString(_("Error: ") + szString, t);
             break;
 
         case wxLOG_Warning:
-            DoLogString(wxString(_("Warning: ")) + szString, t);
+            LogString(_("Warning: ") + szString, t);
             break;
 
         case wxLOG_Info:
         case wxLOG_Message:
         case wxLOG_Status:
         default:    // log unknown log levels too
-                DoLogString(szString, t);
+                LogString(szString, t);
             break;
 
         case wxLOG_Trace:
                 wxString msg = level == wxLOG_Trace ? wxT("Trace: ")
                                                     : wxT("Debug: ");
                 msg << szString;
-                DoLogString(msg, t);
+                LogString(msg, t);
             }
 #endif // Debug
             break;
     }
 }
 
-void wxLog::DoLogString(const wxChar *WXUNUSED(szString), time_t WXUNUSED(t))
+void wxLog::DoLogString(const wxString& szString, time_t t)
 {
+#if WXWIN_COMPATIBILITY_2_8
+    // DoLogString() signature changed since 2.8, so we call the old versions
+    // here so that existing custom log classes still work; unfortunately this
+    // also means that we can't have the wxFAIL_MSG below in compat mode
+    DoLogString((const char*)szString.mb_str(), t);
+    DoLogString((const wchar_t*)szString.wc_str(), t);
+#else
     wxFAIL_MSG(wxT("DoLogString must be overriden if it's called."));
+    wxUnusedVar(szString);
+    wxUnusedVar(t);
+#endif
 }
 
 void wxLog::Flush()
     // nothing to do here
 }
 
-/*static*/ bool wxLog::IsAllowedTraceMask(const wxChar *mask)
+/*static*/ bool wxLog::IsAllowedTraceMask(const wxString& mask)
 {
     for ( wxArrayString::iterator it = ms_aTraceMasks.begin(),
                                   en = ms_aTraceMasks.end();
     }
 }
 
-void wxLogBuffer::DoLog(wxLogLevel level, const wxChar *szString, time_t t)
+void wxLogBuffer::DoLog(wxLogLevel level, const wxString& szString, time_t t)
 {
     switch ( level )
     {
     }
 }
 
-void wxLogBuffer::DoLogString(const wxChar *szString, time_t WXUNUSED(t))
+void wxLogBuffer::DoLogString(const wxString& szString, time_t WXUNUSED(t))
 {
     m_str << szString << _T("\n");
 }
         m_fp = fp;
 }
 
-void wxLogStderr::DoLogString(const wxChar *szString, time_t WXUNUSED(t))
+void wxLogStderr::DoLogString(const wxString& szString, time_t WXUNUSED(t))
 {
     wxString str;
     TimeStamp(&str);
         m_ostr = ostr;
 }
 
-void wxLogStream::DoLogString(const wxChar *szString, time_t WXUNUSED(t))
+void wxLogStream::DoLogString(const wxString& szString, time_t WXUNUSED(t))
 {
-    wxString str;
-    TimeStamp(&str);
-    (*m_ostr) << wxConvertWX2MB(str) << wxConvertWX2MB(szString) << wxSTD endl;
+    wxString stamp;
+    TimeStamp(&stamp);
+    (*m_ostr) << stamp << szString << wxSTD endl;
 }
 #endif // wxUSE_STD_IOSTREAM
 
         m_logNew->Flush();
 }
 
-void wxLogChain::DoLog(wxLogLevel level, const wxChar *szString, time_t t)
+void wxLogChain::DoLog(wxLogLevel level, const wxString& szString, time_t t)
 {
     // let the previous logger show it
     if ( m_logOld && IsPassingMessages() )
 
 
 // this function is a wrapper around strftime(3)
 // allows to exclude the usage of wxDateTime
-static wxString TimeStamp(const wxChar *format, time_t t)
+static wxString TimeStamp(const wxString& format, time_t t)
 {
 #if wxUSE_DATETIME
     wxChar buf[4096];
 }
 
 // log all kinds of messages
-void wxLogGui::DoLog(wxLogLevel level, const wxChar *szString, time_t t)
+void wxLogGui::DoLog(wxLogLevel level, const wxString& szString, time_t t)
 {
     switch ( level ) {
         case wxLOG_Info:
     m_pLogFrame->Show(bShow);
 }
 
-void wxLogWindow::DoLog(wxLogLevel level, const wxChar *szString, time_t t)
+void wxLogWindow::DoLog(wxLogLevel level, const wxString& szString, time_t t)
 {
     // first let the previous logger show it
     wxLogPassThrough::DoLog(level, szString, t);
             case wxLOG_Status:
                 // by default, these messages are ignored by wxLog, so process
                 // them ourselves
-                if ( !wxIsEmpty(szString) )
+                if ( !szString.empty() )
                 {
                     wxString str;
                     str << _("Status: ") << szString;
-                    DoLogString(str, t);
+                    LogString(str, t);
                 }
                 break;
 
     }
 }
 
-void wxLogWindow::DoLogString(const wxChar *szString, time_t WXUNUSED(t))
+void wxLogWindow::DoLogString(const wxString& szString, time_t WXUNUSED(t))
 {
     // put the text into our window
     wxTextCtrl *pText = m_pLogFrame->TextCtrl();
     m_pTextCtrl = pTextCtrl;
 }
 
-void wxLogTextCtrl::DoLogString(const wxChar *szString, time_t WXUNUSED(t))
+void wxLogTextCtrl::DoLogString(const wxString& szString, time_t WXUNUSED(t))
 {
     wxString msg;
     TimeStamp(&msg);