From 2afb9e169048b77a41c63b4f4eea3b10daee641a Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Thu, 24 May 2007 12:50:42 +0000
Subject: [PATCH] 1. Derive wxMessageDialogBase from wxDialog (why did we use
 multiple    inheritance here?), moved more wxMessageDialog fields into the
 base class 2. Added functions to set the text of message box buttons (patch
 1700393,    currently only implemented for wxMac) 3. Added
 wxMessageDialog::SetMessage() and SetExtendedMessage() and    implemented
 them for wxMac (part of the patch), wxGTK 2.4+ and in    a generic way for
 everybody else 4. Allow changing the dialog attributes between creating and
 showing it,    for this the real dialog creation is now done on in
 ShowModal() in all    ports

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@46199 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt               |   2 +
 docs/latex/wx/msgdlg.tex       |  72 +++++++++++++++++++++
 include/wx/generic/msgdlgg.h   |  39 ++++++------
 include/wx/gtk/msgdlg.h        |  24 +++----
 include/wx/mac/carbon/msgdlg.h |  37 +++++------
 include/wx/motif/msgdlg.h      |  30 ++++-----
 include/wx/msgdlg.h            | 110 ++++++++++++++++++++++++++-------
 include/wx/msw/msgdlg.h        |  34 +++++-----
 include/wx/os2/msgdlg.h        |  24 +++----
 include/wx/palmos/msgdlg.h     |  33 ++++------
 samples/dialogs/dialogs.cpp    |  15 ++++-
 src/generic/msgdlgg.cpp        |  34 +++++++---
 src/gtk/msgdlg.cpp             |  84 +++++++++++++++++--------
 src/mac/carbon/msgdlg.cpp      |  95 +++++++++++++++++++++-------
 src/motif/msgdlg.cpp           |  14 +----
 src/msw/msgdlg.cpp             |  14 +----
 src/os2/msgdlg.cpp             |  20 ++----
 src/palmos/msgdlg.cpp          |  14 +----
 18 files changed, 431 insertions(+), 264 deletions(-)

diff --git a/docs/changes.txt b/docs/changes.txt
index ad4a96e641..56730a7cde 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -100,6 +100,7 @@ All (GUI):
 - Added wxDC::StretchBlit() for wxMac and wxMSW (Vince Harron)
 - Added support for drop down toolbar buttons (Tim Kosse)
 - Added support for labels for toolbar controls (Vince Harron)
+- Added wxMessageDialog::SetMessage() and SetExtendedMessage()
 - Added wxEventBlocker class (Francesco Montorsi).
 - Added wxFile/DirPickerCtrl::Get/SetFile/DirName() (Francesco Montorsi).
 - Added wxSizerFlags::Top() and Bottom().
@@ -135,6 +136,7 @@ wxGTK:
 wxMac:
 
 - Better IconRef support (Alan Shouls)
+- Added support for changing button labels in wxMessageDialog (Gareth Simpson)
 - Fix duplicate (empty) help menu in non-English programs (Andreas Jacobs)
 - Allow accelerators to be used with buttons too (Ryan Wilcox)
 - Support resource forks in wxCopyFile() (Hank Schultz)
diff --git a/docs/latex/wx/msgdlg.tex b/docs/latex/wx/msgdlg.tex
index bd2082f8a5..ef51c0940c 100644
--- a/docs/latex/wx/msgdlg.tex
+++ b/docs/latex/wx/msgdlg.tex
@@ -20,6 +20,7 @@ with a choice of OK, Yes, No and Cancel buttons.
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
+
 \membersection{wxMessageDialog::wxMessageDialog}\label{wxmessagedialogctor}
 
 \func{}{wxMessageDialog}{\param{wxWindow* }{parent}, \param{const wxString\& }{message},\rtfsp
@@ -56,15 +57,86 @@ Constructor. Use \helpref{wxMessageDialog::ShowModal}{wxmessagedialogshowmodal}
 
 \docparam{pos}{Dialog position. Not Windows.}
 
+
 \membersection{wxMessageDialog::\destruct{wxMessageDialog}}\label{wxmessagedialogdtor}
 
 \func{}{\destruct{wxMessageDialog}}{\void}
 
 Destructor.
 
+
 \membersection{wxMessageDialog::ShowModal}\label{wxmessagedialogshowmodal}
 
 \func{int}{ShowModal}{\void}
 
 Shows the dialog, returning one of wxID\_OK, wxID\_CANCEL, wxID\_YES, wxID\_NO.
 
+
+\membersection{wxMessageDialog::SetYesNoLabels}\label{wxmessagedialogsetyesnolabels}
+
+\func{bool}{SetYesNoLabels}{\param{const wxString&}{yes},\param{const wxString&}{no}}
+
+Overrides the default labels of the Yes and No buttons.
+
+Notice that this function is not currently available on all platforms, so it
+may return \false to indicate that the labels couldn't be changed. If it
+returns \true (currently only under wxMac), the labels were set successfully.
+Typically, if the function was used successfully, the main dialog message may
+need to be changed, e.g.:
+\begin{verbatim}
+    wxMessageDialog dlg(...);
+    if ( dlg.SetYesNoLabels(_("&Quit"), _("&Don't quit")) )
+        dlg.SetMessage(_("What do you want to do?"));
+    else // buttons have standard "Yes"/"No" values, so rephrase the question
+        dlg.SetMessage(_("Do you really want to quit?"));
+\end{verbatim}
+
+
+\membersection{wxMessageDialog::SetYesNoCancelLabels}\label{wxmessagedialogsetyesnocancellabels}
+
+\func{bool}{SetYesNoCancelLabels}{\param{const wxString&}{yes},\param{const wxString&}{no},\param{const wxString&}{cancel}}
+
+Overrides the default labels of the Yes, No and Cancel buttons.
+
+Please see the remarks in 
+\helpref{SetYesNoLabels}{wxmessagedialogsetyesnolabels} documentation.
+
+
+\membersection{wxMessageDialog::SetOKLabel}\label{wxmessagedialogsetyesoklabel}
+
+\func{bool}{SetOKLabel}{\param{const wxString&}{ok}}
+
+Overrides the default label of the OK button.
+
+Please see the remarks in 
+\helpref{SetYesNoLabels}{wxmessagedialogsetyesnolabels} documentation.
+
+
+\membersection{wxMessageDialog::SetOKCancelLabels}\label{wxmessagedialogsetokcancellabels}
+
+\func{bool}{SetOKCancelLabels}{\param{const wxString&}{ok},\param{const wxString&}{cancel}}
+
+Overrides the default labels of the OK and Cancel buttons.
+
+Please see the remarks in 
+\helpref{SetYesNoLabels}{wxmessagedialogsetyesnolabels} documentation.
+
+
+\membersection{wxMessageDialog::SetMessage}\label{wxmessagedialogsetmessage}
+
+\func{void}{SetMessage}{\param{const wxString&}{msg}}
+
+Sets the message shown by the dialog.
+
+
+\membersection{wxMessageDialog::SetExtendedMessage}\label{wxmessagedialogsetextendedmessage}
+
+\func{void}{SetExtendedMessage}{\param{const wxString&}{exMsg}
+
+Sets the extended message for the dialog: this message is usually an extension
+of the short message specified in the constructor or set with 
+\helpref{SetMessage}{wxmessagedialogsetmessage}. If it is set, the main message
+appears highlighted -- if supported -- and this message appears beneath it in
+normal font. On the platforms which don't support extended messages, it is
+simply appended to the normal message with a new line separating them.
+
diff --git a/include/wx/generic/msgdlgg.h b/include/wx/generic/msgdlgg.h
index d9fa1cc712..9e3bbcff9d 100644
--- a/include/wx/generic/msgdlgg.h
+++ b/include/wx/generic/msgdlgg.h
@@ -9,36 +9,33 @@
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifndef __MSGDLGH_G__
-#define __MSGDLGH_G__
+#ifndef _WX_GENERIC_MSGDLGG_H_
+#define _WX_GENERIC_MSGDLGG_H_
 
-#include "wx/defs.h"
-#include "wx/dialog.h"
-
-// type is an 'or' (|) of wxOK, wxCANCEL, wxYES_NO
-// Returns wxYES/NO/OK/CANCEL
-
-extern WXDLLEXPORT_DATA(const wxChar) wxMessageBoxCaptionStr[];
-
-class WXDLLEXPORT wxGenericMessageDialog: public wxDialog, public wxMessageDialogBase
+class WXDLLEXPORT wxGenericMessageDialog : public wxMessageDialogBase
 {
-DECLARE_DYNAMIC_CLASS(wxGenericMessageDialog)
-
 public:
-    wxGenericMessageDialog(wxWindow *parent, const wxString& message,
-        const wxString& caption = wxMessageBoxCaptionStr,
-        long style = wxOK|wxCENTRE, const wxPoint& pos = wxDefaultPosition);
+    wxGenericMessageDialog(wxWindow *parent,
+                           const wxString& message,
+                           const wxString& caption = wxMessageBoxCaptionStr,
+                           long style = wxOK|wxCENTRE,
+                           const wxPoint& pos = wxDefaultPosition);
 
+    virtual int ShowModal();
+
+protected:
     void OnYes(wxCommandEvent& event);
     void OnNo(wxCommandEvent& event);
     void OnCancel(wxCommandEvent& event);
 
 private:
+    void DoCreateMsgdialog();
+
+    wxPoint m_pos;
+    bool m_created;
+
     DECLARE_EVENT_TABLE()
+    DECLARE_DYNAMIC_CLASS(wxGenericMessageDialog)
 };
 
-#if (!defined( __WXMSW__ ) && !defined( __WXMAC__) && !defined(__WXPM__)) || defined(__WXUNIVERSAL__)
-#define wxMessageDialog wxGenericMessageDialog
-#endif
-
-#endif // __MSGDLGH_G__
+#endif // _WX_GENERIC_MSGDLGG_H_
diff --git a/include/wx/gtk/msgdlg.h b/include/wx/gtk/msgdlg.h
index 58f2403194..98c48c80a8 100644
--- a/include/wx/gtk/msgdlg.h
+++ b/include/wx/gtk/msgdlg.h
@@ -9,27 +9,18 @@
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifndef __MSGDLG_H__
-#define __MSGDLG_H__
+#ifndef _WX_GTK_MSGDLG_H_
+#define _WX_GTK_MSGDLG_H_
 
-#include "wx/defs.h"
-#include "wx/dialog.h"
-
-// type is an 'or' (|) of wxOK, wxCANCEL, wxYES_NO
-// Returns wxYES/NO/OK/CANCEL
-
-WXDLLEXPORT_DATA(extern const wxChar) wxMessageBoxCaptionStr[];
-
-class WXDLLEXPORT wxMessageDialog: public wxDialog, public wxMessageDialogBase
+class WXDLLEXPORT wxMessageDialog : public wxMessageDialogBase
 {
 public:
     wxMessageDialog(wxWindow *parent, const wxString& message,
                     const wxString& caption = wxMessageBoxCaptionStr,
                     long style = wxOK|wxCENTRE,
                     const wxPoint& pos = wxDefaultPosition);
-    virtual ~wxMessageDialog();
 
-    int ShowModal();
+    virtual int ShowModal();
     virtual bool Show( bool WXUNUSED(show) = true ) { return false; };
 
 protected:
@@ -42,10 +33,11 @@ protected:
                               int WXUNUSED(width), int WXUNUSED(height)) {}
 
 private:
-    wxString m_caption;
-    wxString m_message;
+    // create the real GTK+ dialog: this is done from ShowModal() to allow
+    // changing the message between constructing the dialog and showing it
+    void GTKCreateMsgDialog();
 
     DECLARE_DYNAMIC_CLASS(wxMessageDialog)
 };
 
-#endif
+#endif // _WX_GTK_MSGDLG_H_
diff --git a/include/wx/mac/carbon/msgdlg.h b/include/wx/mac/carbon/msgdlg.h
index c74734d9d2..2d00d5df3b 100644
--- a/include/wx/mac/carbon/msgdlg.h
+++ b/include/wx/mac/carbon/msgdlg.h
@@ -13,23 +13,8 @@
 #ifndef _WX_MSGBOXDLG_H_
 #define _WX_MSGBOXDLG_H_
 
-#include "wx/defs.h"
-#include "wx/dialog.h"
-
-/*
- * Message box dialog
- */
-
-WXDLLEXPORT_DATA(extern const wxChar) wxMessageBoxCaptionStr[];
-
-class WXDLLEXPORT wxMessageDialog: public wxDialog, public wxMessageDialogBase
+class WXDLLEXPORT wxMessageDialog : public wxMessageDialogBase
 {
-    DECLARE_DYNAMIC_CLASS(wxMessageDialog)
-
-protected:
-    wxString    m_caption;
-    wxString    m_message;
-    wxWindow *  m_parent;
 public:
     wxMessageDialog(wxWindow *parent,
                     const wxString& message,
@@ -37,15 +22,27 @@ public:
                     long style = wxOK|wxCENTRE,
                     const wxPoint& pos = wxDefaultPosition);
 
-    int ShowModal();
+    virtual int ShowModal();
+
+    // customization of the message box
+    virtual bool SetYesNoLabels(const wxString& yes,const wxString& no);
+    virtual bool SetYesNoCancelLabels(const wxString& yes, const wxString& no, const wxString& cancel);
+    virtual bool SetOKLabel(const wxString& ok);
+    virtual bool SetOKCancelLabels(const wxString& ok, const wxString& cancel);
 
 protected:
-    // not supported for message dialog, RR
+    // not supported for message dialog
     virtual void DoSetSize(int WXUNUSED(x), int WXUNUSED(y),
                            int WXUNUSED(width), int WXUNUSED(height),
                            int WXUNUSED(sizeFlags) = wxSIZE_AUTO) {}
 
+    // labels for the buttons
+    wxString m_yes,
+             m_no,
+             m_ok,
+             m_cancel;
+
+    DECLARE_DYNAMIC_CLASS(wxMessageDialog)
 };
 
-#endif
-    // _WX_MSGBOXDLG_H_
+#endif // _WX_MSGBOXDLG_H_
diff --git a/include/wx/motif/msgdlg.h b/include/wx/motif/msgdlg.h
index e479425a70..08001bd7ab 100644
--- a/include/wx/motif/msgdlg.h
+++ b/include/wx/motif/msgdlg.h
@@ -13,38 +13,32 @@
 #ifndef _WX_MSGBOXDLG_H_
 #define _WX_MSGBOXDLG_H_
 
-#include "wx/defs.h"
-#include "wx/dialog.h"
-
 // ----------------------------------------------------------------------------
 // Message box dialog
 // ----------------------------------------------------------------------------
 
-WXDLLEXPORT_DATA(extern const wxChar) wxMessageBoxCaptionStr[];
-
-class WXDLLEXPORT wxMessageDialog: public wxDialog, public wxMessageDialogBase
+class WXDLLEXPORT wxMessageDialog : public wxMessageDialogBase
 {
-    DECLARE_DYNAMIC_CLASS(wxMessageDialog)
-
 public:
     wxMessageDialog(wxWindow *parent,
-        const wxString& message,
-        const wxString& caption = wxMessageBoxCaptionStr,
-        long style = wxOK | wxCENTRE,
-        const wxPoint& pos = wxDefaultPosition);
+                    const wxString& message,
+                    const wxString& caption = wxMessageBoxCaptionStr,
+                    long style = wxOK | wxCENTRE,
+                    const wxPoint& WXUNUSED(pos) = wxDefaultPosition)
+        : wxMessageDialogBase(parent, message, caption, style)
+    {
+    }
 
-    int ShowModal();
+    virtual int ShowModal();
 
     // implementation only from now on
     // called by the Motif callback
     void SetResult(long result) { m_result = result; }
 
 protected:
-    wxString    m_caption;
-    wxString    m_message;
-    wxWindow *  m_parent;
     long        m_result;
+
+    DECLARE_DYNAMIC_CLASS(wxMessageDialog)
 };
 
-#endif
-// _WX_MSGBOXDLG_H_
+#endif // _WX_MSGBOXDLG_H_
diff --git a/include/wx/msgdlg.h b/include/wx/msgdlg.h
index 8c367fb9b6..6f48c11f2b 100644
--- a/include/wx/msgdlg.h
+++ b/include/wx/msgdlg.h
@@ -16,8 +16,66 @@
 
 #if wxUSE_MSGDLG
 
-class WXDLLEXPORT wxMessageDialogBase
+#include "wx/dialog.h"
+
+WXDLLEXPORT_DATA(extern const wxChar) wxMessageBoxCaptionStr[];
+
+class WXDLLEXPORT wxMessageDialogBase : public wxDialog
 {
+public:
+    // ctors
+    wxMessageDialogBase() { m_dialogStyle = 0; }
+    wxMessageDialogBase(wxWindow *parent,
+                        const wxString& message,
+                        const wxString& caption,
+                        long style)
+        : m_message(message),
+          m_caption(caption)
+    {
+        m_parent = parent;
+        SetMessageDialogStyle(style);
+    }
+
+    // virtual dtor for the base class
+    virtual ~wxMessageDialogBase() { }
+
+
+    // methods for setting up more custom message dialogs -- all functions
+    // return false if they're not implemented
+    virtual bool SetYesNoLabels(const wxString& WXUNUSED(yes),
+                                const wxString& WXUNUSED(no))
+    {
+        return false;
+    }
+
+    virtual bool SetYesNoCancelLabels(const wxString& WXUNUSED(yes),
+                                      const wxString& WXUNUSED(no),
+                                      const wxString& WXUNUSED(cancel))
+    {
+        return false;
+    }
+
+    virtual bool SetOKLabel(const wxString& WXUNUSED(ok))
+    {
+        return false;
+    }
+
+    virtual bool SetOKCancelLabels(const wxString& WXUNUSED(ok),
+                                   const wxString& WXUNUSED(cancel))
+    {
+        return false;
+    }
+
+    virtual void SetMessage(const wxString& message)
+    {
+        m_message = message;
+    }
+
+    virtual void SetExtendedMessage(const wxString& extendedMessage)
+    {
+        m_extendedMessage = extendedMessage;
+    }
+
 protected:
     // common validation of wxMessageDialog style
     void SetMessageDialogStyle(long style)
@@ -30,37 +88,46 @@ protected:
 
         m_dialogStyle = style;
     }
-    inline long GetMessageDialogStyle() const
+
+    long GetMessageDialogStyle() const { return m_dialogStyle; }
+
+
+    // for the platforms not supporting separate main and extended messages
+    // this function should be used to combine both of them in a single string
+    wxString GetFullMessage() const
     {
-        return m_dialogStyle;
+        wxString msg = m_message;
+        if ( !m_extendedMessage.empty() )
+            msg << "\n\n" << m_extendedMessage;
+
+        return msg;
     }
 
-private:
+    wxString m_message,
+             m_extendedMessage,
+             m_caption;
     long m_dialogStyle;
 };
 
-#if defined(__WX_COMPILING_MSGDLGG_CPP__)
-#include "wx/generic/msgdlgg.h"
-#elif defined(__WXUNIVERSAL__) || defined(__WXGPE__)
-#include "wx/generic/msgdlgg.h"
+#if defined(__WX_COMPILING_MSGDLGG_CPP__) || \
+    defined(__WXUNIVERSAL__) || defined(__WXGPE__) || \
+    defined(__WXCOCOA__) || \
+    (defined(__WXGTK__) && !defined(__WXGTK20__))
+    #include "wx/generic/msgdlgg.h"
+
+    #define wxMessageDialog wxGenericMessageDialog
 #elif defined(__WXPALMOS__)
-#include "wx/palmos/msgdlg.h"
+    #include "wx/palmos/msgdlg.h"
 #elif defined(__WXMSW__)
-#include "wx/msw/msgdlg.h"
+    #include "wx/msw/msgdlg.h"
 #elif defined(__WXMOTIF__)
-#include "wx/motif/msgdlg.h"
+    #include "wx/motif/msgdlg.h"
 #elif defined(__WXGTK20__)
-#include "wx/gtk/msgdlg.h"
-#elif defined(__WXGTK__)
-#include "wx/generic/msgdlgg.h"
-#elif defined(__WXGTK__)
-#include "wx/generic/msgdlgg.h"
+    #include "wx/gtk/msgdlg.h"
 #elif defined(__WXMAC__)
-#include "wx/mac/msgdlg.h"
-#elif defined(__WXCOCOA__)
-#include "wx/generic/msgdlgg.h"
+    #include "wx/mac/msgdlg.h"
 #elif defined(__WXPM__)
-#include "wx/os2/msgdlg.h"
+    #include "wx/os2/msgdlg.h"
 #endif
 
 // ----------------------------------------------------------------------------
@@ -75,5 +142,4 @@ int WXDLLEXPORT wxMessageBox(const wxString& message,
 
 #endif // wxUSE_MSGDLG
 
-#endif
-    // _WX_MSGDLG_H_BASE_
+#endif // _WX_MSGDLG_H_BASE_
diff --git a/include/wx/msw/msgdlg.h b/include/wx/msw/msgdlg.h
index a20b51b2ae..95c61af4e3 100644
--- a/include/wx/msw/msgdlg.h
+++ b/include/wx/msw/msgdlg.h
@@ -12,31 +12,25 @@
 #ifndef _WX_MSGBOXDLG_H_
 #define _WX_MSGBOXDLG_H_
 
-#include "wx/defs.h"
-#include "wx/dialog.h"
-
-/*
- * Message box dialog
- */
-
-extern WXDLLEXPORT_DATA(const wxChar) wxMessageBoxCaptionStr[];
-
-class WXDLLEXPORT wxMessageDialog: public wxDialog, public wxMessageDialogBase
+class WXDLLEXPORT wxMessageDialog : public wxMessageDialogBase
 {
-DECLARE_DYNAMIC_CLASS(wxMessageDialog)
-protected:
-    wxString    m_caption;
-    wxString    m_message;
-    wxWindow *  m_parent;
 public:
-    wxMessageDialog(wxWindow *parent, const wxString& message, const wxString& caption = wxMessageBoxCaptionStr,
-        long style = wxOK|wxCENTRE, const wxPoint& pos = wxDefaultPosition);
+    wxMessageDialog(wxWindow *parent,
+                    const wxString& message,
+                    const wxString& caption = wxMessageBoxCaptionStr,
+                    long style = wxOK|wxCENTRE,
+                    const wxPoint& WXUNUSED(pos) = wxDefaultPosition)
+        : wxMessageDialogBase(parent, message, caption, style)
+    {
+    }
+
 
-    int ShowModal(void);
+    virtual int ShowModal();
 
+protected:
+    DECLARE_DYNAMIC_CLASS(wxMessageDialog)
     DECLARE_NO_COPY_CLASS(wxMessageDialog)
 };
 
 
-#endif
-    // _WX_MSGBOXDLG_H_
+#endif // _WX_MSGBOXDLG_H_
diff --git a/include/wx/os2/msgdlg.h b/include/wx/os2/msgdlg.h
index 0a08854cbf..9ec111886f 100644
--- a/include/wx/os2/msgdlg.h
+++ b/include/wx/os2/msgdlg.h
@@ -13,31 +13,23 @@
 #ifndef _WX_MSGBOXDLG_H_
 #define _WX_MSGBOXDLG_H_
 
-#include "wx/defs.h"
-#include "wx/dialog.h"
-
-/*
- * Message box dialog
- */
-
-class WXDLLEXPORT wxMessageDialog : public wxDialog, public wxMessageDialogBase
+class WXDLLEXPORT wxMessageDialog : public wxMessageDialogBase
 {
-DECLARE_DYNAMIC_CLASS(wxMessageDialog)
 public:
     wxMessageDialog( wxWindow*       pParent
                     ,const wxString& rsMessage
                     ,const wxString& rsCaption = wxMessageBoxCaptionStr
                     ,long            lStyle = wxOK|wxCENTRE
-                    ,const wxPoint&  rPos = wxDefaultPosition
-                   );
+                    ,const wxPoint&  WXUNUSED(rPos) = wxDefaultPosition
+                   )
+        : wxMessageDialogBase(pParent, rsMessage, rsCaption, lStyle)
+    {
+    }
 
     int ShowModal(void);
 
 protected:
-    wxString                        m_sCaption;
-    wxString                        m_sMessage;
-    wxWindow*                       m_pParent;
+    DECLARE_DYNAMIC_CLASS(wxMessageDialog)
 }; // end of CLASS wxMessageDialog
 
-#endif
-    // _WX_MSGBOXDLG_H_
+#endif // _WX_MSGBOXDLG_H_
diff --git a/include/wx/palmos/msgdlg.h b/include/wx/palmos/msgdlg.h
index 621b297b92..2fadd44d00 100644
--- a/include/wx/palmos/msgdlg.h
+++ b/include/wx/palmos/msgdlg.h
@@ -12,28 +12,21 @@
 #ifndef _WX_MSGBOXDLG_H_
 #define _WX_MSGBOXDLG_H_
 
-#include "wx/defs.h"
-#include "wx/dialog.h"
-
-/*
- * Message box dialog
- */
-
-WXDLLEXPORT_DATA(extern const wxChar) wxMessageBoxCaptionStr[];
-
-class WXDLLEXPORT wxMessageDialog: public wxDialog, public wxMessageDialogBase
+class WXDLLEXPORT wxMessageDialog : public wxMessageDialogBase
 {
-DECLARE_DYNAMIC_CLASS(wxMessageDialog)
-protected:
-    wxString    m_caption;
-    wxString    m_message;
-    wxWindow *  m_parent;
 public:
-    wxMessageDialog(wxWindow *parent, const wxString& message, const wxString& caption = wxMessageBoxCaptionStr,
-        long style = wxOK|wxCENTRE, const wxPoint& pos = wxDefaultPosition);
-
-    int ShowModal(void);
-
+    wxMessageDialog(wxWindow *parent,
+                    const wxString& message,
+                    const wxString& caption = wxMessageBoxCaptionStr,
+                    long style = wxOK|wxCENTRE,
+                    const wxPoint& WXUNUSED(pos) = wxDefaultPosition)
+        : wxMessageDialogBase(parent, message, caption, style)
+    {
+    }
+
+    virtual int ShowModal(void);
+
+    DECLARE_DYNAMIC_CLASS(wxMessageDialog)
     DECLARE_NO_COPY_CLASS(wxMessageDialog)
 };
 
diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp
index 8ab65908e0..fe7338bdf4 100644
--- a/samples/dialogs/dialogs.cpp
+++ b/samples/dialogs/dialogs.cpp
@@ -593,8 +593,19 @@ void MyFrame::LogDialog(wxCommandEvent& WXUNUSED(event))
 
 void MyFrame::MessageBox(wxCommandEvent& WXUNUSED(event) )
 {
-    wxMessageDialog dialog( NULL, _T("This is a message box\nA long, long string to test out the message box properly"),
-        _T("Message box text"), wxNO_DEFAULT|wxYES_NO|wxCANCEL|wxICON_INFORMATION);
+    wxMessageDialog dialog(NULL,
+                           _T("This is a message box\nA long, long string to test out the message box properly"),
+                           _T("Message box text"),
+                           wxNO_DEFAULT | wxYES_NO | wxCANCEL | wxICON_INFORMATION);
+
+    if ( dialog.SetYesNoLabels(_T("Answer &Yes"),_T("Answer &No")) )
+    {
+        dialog.SetExtendedMessage(_T("This platform supports custom button labels"));
+    }
+    else
+    {
+        dialog.SetExtendedMessage(_T("Custom button labels are not supported."));
+    }
 
     switch ( dialog.ShowModal() )
     {
diff --git a/src/generic/msgdlgg.cpp b/src/generic/msgdlgg.cpp
index 1565d88e4f..c6f2e60f23 100644
--- a/src/generic/msgdlgg.cpp
+++ b/src/generic/msgdlgg.cpp
@@ -60,11 +60,18 @@ wxGenericMessageDialog::wxGenericMessageDialog( wxWindow *parent,
                                                 const wxString& caption,
                                                 long style,
                                                 const wxPoint& pos)
-                      : wxDialog( parent, wxID_ANY, caption, pos, wxDefaultSize, wxDEFAULT_DIALOG_STYLE )
+                      : wxMessageDialogBase(GetParentForModalDialog(parent),
+                                            message,
+                                            caption,
+                                            style),
+                        m_pos(pos)
 {
-    SetMessageDialogStyle(style);
+    m_created = false;
+}
 
-    parent = GetParentForModalDialog(parent);
+void wxGenericMessageDialog::DoCreateMsgdialog()
+{
+    wxDialog::Create(m_parent, wxID_ANY, m_caption, m_pos, wxDefaultSize, wxDEFAULT_DIALOG_STYLE);
 
     bool is_pda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA);
 
@@ -74,10 +81,10 @@ wxGenericMessageDialog::wxGenericMessageDialog( wxWindow *parent,
 
 #if wxUSE_STATBMP
     // 1) icon
-    if (style & wxICON_MASK)
+    if (m_dialogStyle & wxICON_MASK)
     {
         wxBitmap bitmap;
-        switch ( style & wxICON_MASK )
+        switch ( m_dialogStyle & wxICON_MASK )
         {
             default:
                 wxFAIL_MSG(_T("incorrect log style"));
@@ -109,16 +116,16 @@ wxGenericMessageDialog::wxGenericMessageDialog( wxWindow *parent,
 
 #if wxUSE_STATTEXT
     // 2) text
-    icon_text->Add( CreateTextSizer( message ), 0, wxALIGN_CENTER | wxLEFT, 10 );
+    icon_text->Add( CreateTextSizer( GetFullMessage() ), 0, wxALIGN_CENTER | wxLEFT, 10 );
 
     topsizer->Add( icon_text, 1, wxCENTER | wxLEFT|wxRIGHT|wxTOP, 10 );
 #endif // wxUSE_STATTEXT
 
     // 3) buttons
     int center_flag = wxEXPAND;
-    if (style & wxYES_NO)
+    if (m_dialogStyle & wxYES_NO)
         center_flag = wxALIGN_CENTRE;
-    wxSizer *sizerBtn = CreateSeparatedButtonSizer(style & ButtonSizerFlags);
+    wxSizer *sizerBtn = CreateSeparatedButtonSizer(m_dialogStyle & ButtonSizerFlags);
     if ( sizerBtn )
         topsizer->Add(sizerBtn, 0, center_flag | wxALL, 10 );
 
@@ -158,4 +165,15 @@ void wxGenericMessageDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
     }
 }
 
+int wxGenericMessageDialog::ShowModal()
+{
+    if ( !m_created )
+    {
+        m_created = true;
+        DoCreateMsgdialog();
+    }
+
+    return wxMessageDialogBase::ShowModal();
+}
+
 #endif // wxUSE_MSGDLG && !defined(__WXGTK20__)
diff --git a/src/gtk/msgdlg.cpp b/src/gtk/msgdlg.cpp
index ddbecfa54a..14e71134c2 100644
--- a/src/gtk/msgdlg.cpp
+++ b/src/gtk/msgdlg.cpp
@@ -34,57 +34,88 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent,
                                  const wxString& caption,
                                  long style,
                                  const wxPoint& WXUNUSED(pos))
+               : wxMessageDialogBase(GetParentForModalDialog(parent),
+                                     message,
+                                     caption,
+                                     style)
 {
-    m_caption = caption;
-    m_message = message;
-    SetMessageDialogStyle(style);
-
-    m_parent = GetParentForModalDialog(parent);
+}
 
+void wxMessageDialog::GTKCreateMsgDialog()
+{
     GtkMessageType type = GTK_MESSAGE_ERROR;
     GtkButtonsType buttons = GTK_BUTTONS_OK;
 
-    if (style & wxYES_NO)
+    if (m_dialogStyle & wxYES_NO)
     {
-        if (style & wxCANCEL)
+        if (m_dialogStyle & wxCANCEL)
             buttons = GTK_BUTTONS_NONE;
         else
             buttons = GTK_BUTTONS_YES_NO;
     }
 
-    if (style & wxOK)
+    if (m_dialogStyle & wxOK)
     {
-        if (style & wxCANCEL)
+        if (m_dialogStyle & wxCANCEL)
             buttons = GTK_BUTTONS_OK_CANCEL;
         else
             buttons = GTK_BUTTONS_OK;
     }
 
-    if (style & wxICON_EXCLAMATION)
+    if (m_dialogStyle & wxICON_EXCLAMATION)
         type = GTK_MESSAGE_WARNING;
-    else if (style & wxICON_ERROR)
+    else if (m_dialogStyle & wxICON_ERROR)
         type = GTK_MESSAGE_ERROR;
-    else if (style & wxICON_INFORMATION)
+    else if (m_dialogStyle & wxICON_INFORMATION)
         type = GTK_MESSAGE_INFO;
-    else if (style & wxICON_QUESTION)
+    else if (m_dialogStyle & wxICON_QUESTION)
         type = GTK_MESSAGE_QUESTION;
     else
     {
         // GTK+ doesn't have a "typeless" msg box, so try to auto detect...
-        type = style & wxYES ? GTK_MESSAGE_QUESTION : GTK_MESSAGE_INFO;
+        type = m_dialogStyle & wxYES ? GTK_MESSAGE_QUESTION : GTK_MESSAGE_INFO;
     }
 
-    m_widget = gtk_message_dialog_new(m_parent ?
-                                          GTK_WINDOW(m_parent->m_widget) : NULL,
+    wxString message;
+#if GTK_CHECK_VERSION(2, 4, 0)
+    bool needsExtMessage = false;
+    if ( gtk_check_version(2, 4, 0) == NULL && !m_extendedMessage.empty() )
+    {
+        message = m_message;
+        needsExtMessage = true;
+    }
+    else // extended message not needed or not supported
+#endif // GTK+ 2.4+
+    {
+        message = GetFullMessage();
+    }
+
+    m_widget = gtk_message_dialog_new(m_parent ? GTK_WINDOW(m_parent->m_widget)
+                                              : NULL,
                                       GTK_DIALOG_MODAL,
-                                      type, buttons,
-                                      "%s", (const char*)wxGTK_CONV(m_message));
+                                      type,
+                                      buttons,
+                                      "%s",
+                                      (const char*)wxGTK_CONV(message));
+
+#if GTK_CHECK_VERSION(2, 4, 0)
+    if ( needsExtMessage )
+    {
+        gtk_message_dialog_format_secondary_text
+        (
+            (GtkMessageDialog *)m_widget,
+            "%s",
+            (const char *)wxGTK_CONV(m_extendedMessage)
+        );
+    }
+#endif // GTK+ 2.4+
+
     if (m_caption != wxMessageBoxCaptionStr)
         gtk_window_set_title(GTK_WINDOW(m_widget), wxGTK_CONV(m_caption));
 
-    if (style & wxYES_NO)
+    if (m_dialogStyle & wxYES_NO)
     {
-        if (style & wxCANCEL)
+        if (m_dialogStyle & wxCANCEL)
         {
             gtk_dialog_add_button(GTK_DIALOG(m_widget), GTK_STOCK_NO,
                                   GTK_RESPONSE_NO);
@@ -93,7 +124,7 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent,
             gtk_dialog_add_button(GTK_DIALOG(m_widget), GTK_STOCK_YES,
                                   GTK_RESPONSE_YES);
         }
-        if (style & wxNO_DEFAULT)
+        if (m_dialogStyle & wxNO_DEFAULT)
             gtk_dialog_set_default_response(GTK_DIALOG(m_widget), GTK_RESPONSE_NO);
         else
             gtk_dialog_set_default_response(GTK_DIALOG(m_widget), GTK_RESPONSE_YES);
@@ -104,12 +135,15 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent,
                                      GTK_WINDOW(m_parent->m_widget));
 }
 
-wxMessageDialog::~wxMessageDialog()
-{
-}
-
 int wxMessageDialog::ShowModal()
 {
+    if ( !m_widget )
+    {
+        GTKCreateMsgDialog();
+        wxCHECK_MSG( m_widget, wxID_CANCEL,
+                     _T("failed to create GtkMessageDialog") );
+    }
+
     // This should be necessary, but otherwise the
     // parent TLW will disappear..
     if (m_parent)
diff --git a/src/mac/carbon/msgdlg.cpp b/src/mac/carbon/msgdlg.cpp
index e7fc38da40..ade6197a84 100644
--- a/src/mac/carbon/msgdlg.cpp
+++ b/src/mac/carbon/msgdlg.cpp
@@ -24,14 +24,45 @@
 IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
 
 
-wxMessageDialog::wxMessageDialog(
-    wxWindow *parent, const wxString& message, const wxString& caption,
-    long style, const wxPoint& pos )
+wxMessageDialog::wxMessageDialog(wxWindow *parent,
+                                 const wxString& message,
+                                 const wxString& caption,
+                                 long style,
+                                 const wxPoint& pos)
+               : wxMessageDialogBase(parent, message, caption, style)
 {
-    m_caption = caption;
-    m_message = message;
-    m_parent = parent;
-    SetMessageDialogStyle(style);
+    m_yes = _("Yes");
+    m_no  = _("No");
+    m_ok  = _("OK");
+    m_cancel = _("Cancel");
+}
+
+bool wxMessageDialog::SetYesNoLabels(const wxString& yes,const wxString& no)
+{
+    m_yes = yes;
+    m_no = no;
+    return true;
+}
+
+bool wxMessageDialog::SetYesNoCancelLabels(const wxString& yes, const wxString& no, const wxString& cancel)
+{
+    m_yes = yes;
+    m_no = no;
+    m_cancel = cancel;
+    return true;
+}
+
+bool wxMessageDialog::SetOKLabel(const wxString& ok)
+{
+    m_ok = ok;
+    return true;
+}
+
+bool wxMessageDialog::SetOKCancelLabels(const wxString& ok, const wxString& cancel)
+{
+    m_ok = ok;
+    m_cancel = cancel;
+    return true;
 }
 
 int wxMessageDialog::ShowModal()
@@ -52,6 +83,26 @@ int wxMessageDialog::ShowModal()
     else if (style & wxICON_QUESTION)
         alertType = kAlertCautionAlert;
 
+
+    // work out what to display
+    // if the extended text is empty then we use the caption as the title
+    // and the message as the text (for backwards compatibility)
+    // but if the extended message is not empty then we use the message as the title
+    // and the extended message as the text because that makes more sense
+
+    wxString msgtitle,msgtext;
+    if(m_extendedMessage.IsEmpty())
+    {
+        msgtitle = m_caption;
+        msgtext  = m_message;
+    }
+    else
+    {
+        msgtitle = m_message;
+        msgtext  = m_extendedMessage;
+    }
+
+
 #if TARGET_API_MAC_OSX
     if ( !wxIsMainThread() )
     {
@@ -59,13 +110,13 @@ int wxMessageDialog::ShowModal()
         CFStringRef alternateButtonTitle = NULL;
         CFStringRef otherButtonTitle = NULL;
 
-        wxMacCFStringHolder cfTitle( m_caption, m_font.GetEncoding() );
-        wxMacCFStringHolder cfText( m_message, m_font.GetEncoding() );
+        wxMacCFStringHolder cfTitle( msgtitle, m_font.GetEncoding() );
+        wxMacCFStringHolder cfText( msgtext, m_font.GetEncoding() );
 
-        wxMacCFStringHolder cfNoString( _("No"), m_font.GetEncoding() );
-        wxMacCFStringHolder cfYesString( _("Yes"), m_font.GetEncoding() );
-        wxMacCFStringHolder cfOKString( _("OK") , m_font.GetEncoding()) ;
-        wxMacCFStringHolder cfCancelString( _("Cancel"), m_font.GetEncoding() );
+        wxMacCFStringHolder cfNoString( m_no.c_str(), m_font.GetEncoding() );
+        wxMacCFStringHolder cfYesString( m_yes.c_str(), m_font.GetEncoding() );
+        wxMacCFStringHolder cfOKString( m_ok.c_str() , m_font.GetEncoding()) ;
+        wxMacCFStringHolder cfCancelString( m_cancel.c_str(), m_font.GetEncoding() );
 
         int buttonId[4] = { 0, 0, 0, wxID_CANCEL /* time-out */ };
 
@@ -117,11 +168,13 @@ int wxMessageDialog::ShowModal()
         short result;
 
         AlertStdCFStringAlertParamRec param;
-        wxMacCFStringHolder cfNoString( _("No"), m_font.GetEncoding() );
-        wxMacCFStringHolder cfYesString( _("Yes"), m_font.GetEncoding() );
+        wxMacCFStringHolder cfNoString( m_no.c_str(), m_font.GetEncoding() );
+        wxMacCFStringHolder cfYesString( m_yes.c_str(), m_font.GetEncoding() );
+        wxMacCFStringHolder cfOKString( m_ok.c_str(), m_font.GetEncoding() );
+        wxMacCFStringHolder cfCancelString( m_cancel.c_str(), m_font.GetEncoding() );
 
-        wxMacCFStringHolder cfTitle( m_caption, m_font.GetEncoding() );
-        wxMacCFStringHolder cfText( m_message, m_font.GetEncoding() );
+        wxMacCFStringHolder cfTitle( msgtitle, m_font.GetEncoding() );
+        wxMacCFStringHolder cfText( msgtext, m_font.GetEncoding() );
 
         param.movable = true;
         param.flags = 0;
@@ -134,7 +187,7 @@ int wxMessageDialog::ShowModal()
             if (style & wxCANCEL)
             {
                 param.defaultText = cfYesString;
-                param.cancelText = (CFStringRef) kAlertDefaultCancelText;
+                param.cancelText = cfCancelString;
                 param.otherText = cfNoString;
                 param.helpButton = false;
                 param.defaultButton = style & wxNO_DEFAULT ? kAlertStdAlertOtherButton : kAlertStdAlertOKButton;
@@ -156,8 +209,8 @@ int wxMessageDialog::ShowModal()
             if (style & wxCANCEL)
             {
                 // that's a cancel missing
-                param.defaultText = (CFStringRef) kAlertDefaultOKText;
-                param.cancelText = (CFStringRef) kAlertDefaultCancelText;
+                param.defaultText = cfOKString;
+                param.cancelText = cfCancelString;
                 param.otherText = NULL;
                 param.helpButton = false;
                 param.defaultButton = kAlertStdAlertOKButton;
@@ -165,7 +218,7 @@ int wxMessageDialog::ShowModal()
             }
             else
             {
-                param.defaultText = (CFStringRef) kAlertDefaultOKText;
+                param.defaultText = cfOKString;
                 param.cancelText = NULL;
                 param.otherText = NULL;
                 param.helpButton = false;
diff --git a/src/motif/msgdlg.cpp b/src/motif/msgdlg.cpp
index f103cfc0d1..df115f63e7 100644
--- a/src/motif/msgdlg.cpp
+++ b/src/motif/msgdlg.cpp
@@ -99,18 +99,6 @@ static void msgboxCallBackClose(Widget w,
 // wxMessageDialog
 // ----------------------------------------------------------------------------
 
-wxMessageDialog::wxMessageDialog(wxWindow *parent,
-                                 const wxString& message,
-                                 const wxString& caption,
-                                 long style,
-                                 const wxPoint& WXUNUSED(pos))
-{
-    m_caption = caption;
-    m_message = message;
-    m_parent = parent;
-    SetMessageDialogStyle(style);
-}
-
 extern "C"
 {
     typedef Widget (*DialogCreateFunction)(Widget, String, ArgList, Cardinal);
@@ -160,7 +148,7 @@ int wxMessageDialog::ShowModal()
     Arg args[10];
     int ac = 0;
 
-    wxXmString text(m_message);
+    wxXmString text(GetFullMessage());
     wxXmString title(m_caption);
     XtSetArg(args[ac], XmNmessageString, text()); ac++;
     XtSetArg(args[ac], XmNdialogTitle, title()); ac++;
diff --git a/src/msw/msgdlg.cpp b/src/msw/msgdlg.cpp
index 5312a8ec06..83b2d98d22 100644
--- a/src/msw/msgdlg.cpp
+++ b/src/msw/msgdlg.cpp
@@ -33,18 +33,6 @@
 
 IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
 
-wxMessageDialog::wxMessageDialog(wxWindow *parent,
-                                 const wxString& message,
-                                 const wxString& caption,
-                                 long style,
-                                 const wxPoint& WXUNUSED(pos))
-{
-    m_caption = caption;
-    m_message = message;
-    m_parent = parent;
-    SetMessageDialogStyle(style);
-}
-
 int wxMessageDialog::ShowModal()
 {
     if ( !wxTheApp->GetTopWindow() )
@@ -110,7 +98,7 @@ int wxMessageDialog::ShowModal()
     // per MSDN documentation for MessageBox() we can prefix the message with 2
     // right-to-left mark characters to tell the function to use RTL layout
     // (unfortunately this only works in Unicode builds)
-    wxString message = m_message;
+    wxString message = GetFullMessage();
 #if wxUSE_UNICODE
     if ( wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft )
     {
diff --git a/src/os2/msgdlg.cpp b/src/os2/msgdlg.cpp
index 695b88ee35..4504fd97c7 100644
--- a/src/os2/msgdlg.cpp
+++ b/src/os2/msgdlg.cpp
@@ -32,18 +32,6 @@
 
 IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
 
-wxMessageDialog::wxMessageDialog( wxWindow*       WXUNUSED(pParent),
-                                  const wxString& rsMessage,
-                                  const wxString& rsCaption,
-                                  long            lStyle,
-                                  const wxPoint&  WXUNUSED(pPos) )
-{
-    m_sCaption     = rsCaption;
-    m_sMessage     = rsMessage;
-    m_pParent      = NULL; // pParent;
-    SetMessageDialogStyle(lStyle);
-} // end of wxMessageDialog::wxMessageDialog
-
 int wxMessageDialog::ShowModal()
 {
     HWND                            hWnd = 0;
@@ -63,8 +51,8 @@ int wxMessageDialog::ShowModal()
             wxTheApp->Dispatch();
     }
 
-    if (m_pParent)
-        hWnd = (HWND) m_pParent->GetHWND();
+    if (m_parent)
+        hWnd = (HWND) m_parent->GetHWND();
     else
         hWnd = HWND_DESKTOP;
     if (lStyle & wxYES_NO)
@@ -109,8 +97,8 @@ int wxMessageDialog::ShowModal()
 
     ULONG                           ulAns = ::WinMessageBox( hWnd
                                                             ,hWnd
-                                                            ,m_sMessage.c_str()
-                                                            ,m_sCaption.c_str()
+                                                            ,GetFullMessage().c_str()
+                                                            ,m_caption.c_str()
                                                             ,0L
                                                             ,ulStyle);
     switch (ulAns)
diff --git a/src/palmos/msgdlg.cpp b/src/palmos/msgdlg.cpp
index 4c1f7732b5..bde9907eb2 100644
--- a/src/palmos/msgdlg.cpp
+++ b/src/palmos/msgdlg.cpp
@@ -28,18 +28,6 @@
 
 IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
 
-wxMessageDialog::wxMessageDialog(wxWindow *parent,
-                                 const wxString& message,
-                                 const wxString& caption,
-                                 long style,
-                                 const wxPoint& WXUNUSED(pos))
-{
-    m_caption = caption;
-    m_message = message;
-    m_parent = parent;
-    SetMessageDialogStyle(style);
-}
-
 int wxMessageDialog::ShowModal()
 {
     int AlertID=1000;
@@ -111,7 +99,7 @@ int wxMessageDialog::ShowModal()
     DmReleaseResource(AlertHandle);
 
     // Display the dialog
-    Result=FrmCustomAlert(AppDB,AlertID,m_message.c_str(),"","");
+    Result=FrmCustomAlert(AppDB,AlertID,GetFullMessage().c_str(),"","");
 
     // Convert the Palm OS result to wxResult
     if(AlertID<1100)
-- 
2.50.0

