]> git.saurik.com Git - wxWidgets.git/commitdiff
Provide a task-dialog based wxMSW wxMessageDialog implementation.
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 18 Aug 2010 22:48:28 +0000 (22:48 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 18 Aug 2010 22:48:28 +0000 (22:48 +0000)
Use the task dialog instead of the legacy message box for wxMessageDialog
implementation under wxMSW on recent (Vista and later) Windows versions.

As part of this change, remove wxMessageDialogWithCustomLabels and integrate
its functionality in wxMessageDialogBase itself as it's now used by all
platforms.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65348 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

13 files changed:
include/wx/generic/msgdlgg.h
include/wx/gtk/msgdlg.h
include/wx/msgdlg.h
include/wx/msw/msgdlg.h
include/wx/msw/private/msgdlg.h [new file with mode: 0644]
include/wx/osx/msgdlg.h
interface/wx/msgdlg.h
src/generic/msgdlgg.cpp
src/gtk/msgdlg.cpp
src/msw/msgdlg.cpp
src/osx/carbon/msgdlg.cpp
src/osx/cocoa/msgdlg.mm
src/osx/iphone/msgdlg.mm

index be63dcd910dff5acec9424c66152d76a961d4508..8238ccd7d1aed39ec6248b0568e964e14c52c72d 100644 (file)
@@ -24,13 +24,19 @@ public:
     virtual int ShowModal();
 
 protected:
+    // Creates a message dialog taking any options that have been set after
+    // object creation into account such as custom labels.
+    void DoCreateMsgdialog();
+
     void OnYes(wxCommandEvent& event);
     void OnNo(wxCommandEvent& event);
     void OnCancel(wxCommandEvent& event);
 
-private:
-    void DoCreateMsgdialog();
+    // can be overridden to provide more contents to the dialog
+    virtual void AddMessageDialogCheckBox(wxSizer *WXUNUSED(sizer)) { }
+    virtual void AddMessageDialogDetails(wxSizer *WXUNUSED(sizer)) { }
 
+private:
     wxPoint m_pos;
     bool m_created;
 
index 785a0b18e2ac57da4937839bd32a7675660d21e1..daab4caac938e91b60648b45c88cb86a9a6d1b1b 100644 (file)
@@ -12,7 +12,7 @@
 #ifndef _WX_GTK_MSGDLG_H_
 #define _WX_GTK_MSGDLG_H_
 
-class WXDLLIMPEXP_CORE wxMessageDialog : public wxMessageDialogWithCustomLabels
+class WXDLLIMPEXP_CORE wxMessageDialog : public wxMessageDialogBase
 {
 public:
     wxMessageDialog(wxWindow *parent, const wxString& message,
index de2d6abe1bc060aee36ba40d32931230762769c3..7e2eb5c80cb9ee59695f855d9b80c8258ffbd820 100644 (file)
@@ -84,7 +84,6 @@ public:
         const int m_stockId;
     };
 
-
     // ctors
     wxMessageDialogBase() { m_dialogStyle = 0; }
     wxMessageDialogBase(wxWindow *parent,
@@ -101,43 +100,22 @@ public:
     // 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 ButtonLabel& WXUNUSED(yes),
-                                const ButtonLabel& WXUNUSED(no))
-    {
-        return false;
-    }
-
-    virtual bool SetYesNoCancelLabels(const ButtonLabel& WXUNUSED(yes),
-                                      const ButtonLabel& WXUNUSED(no),
-                                      const ButtonLabel& WXUNUSED(cancel))
-    {
-        return false;
-    }
-
-    virtual bool SetOKLabel(const ButtonLabel& WXUNUSED(ok))
-    {
-        return false;
-    }
-
-    virtual bool SetOKCancelLabels(const ButtonLabel& WXUNUSED(ok),
-                                   const ButtonLabel& WXUNUSED(cancel))
-    {
-        return false;
-    }
+    wxString GetCaption() const { return m_caption; }
 
     virtual void SetMessage(const wxString& message)
     {
         m_message = message;
     }
 
-    virtual void SetExtendedMessage(const wxString& extendedMessage)
+    wxString GetMessage() const { return m_message; }
+
+    void SetExtendedMessage(const wxString& extendedMessage)
     {
         m_extendedMessage = extendedMessage;
     }
 
+    wxString GetExtendedMessage() const { return m_extendedMessage; }
+
     // change the dialog style flag
     void SetMessageDialogStyle(long style)
     {
@@ -165,74 +143,8 @@ public:
         m_dialogStyle = style;
     }
 
-protected:
     long GetMessageDialogStyle() const { return m_dialogStyle; }
 
-    // based on message dialog style, returns exactly one of: wxICON_NONE,
-    // wxICON_ERROR, wxICON_WARNING, wxICON_QUESTION, wxICON_INFORMATION
-    long GetEffectiveIcon() const
-    {
-        if ( m_dialogStyle & wxICON_NONE )
-            return wxICON_NONE;
-        else if ( m_dialogStyle & wxICON_ERROR )
-            return wxICON_ERROR;
-        else if ( m_dialogStyle & wxICON_WARNING )
-            return wxICON_WARNING;
-        else if ( m_dialogStyle & wxICON_QUESTION )
-            return wxICON_QUESTION;
-        else if ( m_dialogStyle & wxICON_INFORMATION )
-            return wxICON_INFORMATION;
-        else if ( m_dialogStyle & wxYES )
-            return wxICON_QUESTION;
-        else
-            return wxICON_INFORMATION;
-    }
-
-
-    // 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
-    {
-        wxString msg = m_message;
-        if ( !m_extendedMessage.empty() )
-            msg << "\n\n" << m_extendedMessage;
-
-        return msg;
-    }
-
-    wxString m_message,
-             m_extendedMessage,
-             m_caption;
-    long m_dialogStyle;
-
-    wxDECLARE_NO_COPY_CLASS(wxMessageDialogBase);
-};
-
-// this is a helper class for native wxMessageDialog implementations which need
-// to store the custom button labels as member variables and then use them in
-// ShowModal() (there could conceivably be a port which would have some native
-// functions for setting these labels immediately and we also don't need to
-// store them at all if custom labels are not supported, which is why we do
-// this in a separate class and not wxMessageDialogBase itself)
-#if defined(__WXCOCOA__) || \
-    defined(__WXGTK20__) || \
-    defined(__WXMAC__) || \
-    defined(__WXMSW__)
-
-class WXDLLIMPEXP_CORE wxMessageDialogWithCustomLabels
-    : public wxMessageDialogBase
-{
-public:
-    // ctors
-    wxMessageDialogWithCustomLabels() { }
-    wxMessageDialogWithCustomLabels(wxWindow *parent,
-                                    const wxString& message,
-                                    const wxString& caption,
-                                    long style)
-        : wxMessageDialogBase(parent, message, caption, style)
-    {
-    }
-
     // customization of the message box buttons
     virtual bool SetYesNoLabels(const ButtonLabel& yes,const ButtonLabel& no)
     {
@@ -265,7 +177,6 @@ public:
         return true;
     }
 
-protected:
     // test if any custom labels were set
     bool HasCustomLabels() const
     {
@@ -285,6 +196,43 @@ protected:
     wxString GetCancelLabel() const
         { return m_cancel.empty() ? GetDefaultCancelLabel() : m_cancel; }
 
+    // based on message dialog style, returns exactly one of: wxICON_NONE,
+    // wxICON_ERROR, wxICON_WARNING, wxICON_QUESTION, wxICON_INFORMATION
+    long GetEffectiveIcon() const
+    {
+        if ( m_dialogStyle & wxICON_NONE )
+            return wxICON_NONE;
+        else if ( m_dialogStyle & wxICON_ERROR )
+            return wxICON_ERROR;
+        else if ( m_dialogStyle & wxICON_WARNING )
+            return wxICON_WARNING;
+        else if ( m_dialogStyle & wxICON_QUESTION )
+            return wxICON_QUESTION;
+        else if ( m_dialogStyle & wxICON_INFORMATION )
+            return wxICON_INFORMATION;
+        else if ( m_dialogStyle & wxYES )
+            return wxICON_QUESTION;
+        else
+            return wxICON_INFORMATION;
+    }
+
+protected:
+    // 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
+    {
+        wxString msg = m_message;
+        if ( !m_extendedMessage.empty() )
+            msg << "\n\n" << m_extendedMessage;
+
+        return msg;
+    }
+
+    wxString m_message,
+             m_extendedMessage,
+             m_caption;
+    long m_dialogStyle;
+
     // this function is called by our public SetXXXLabels() and should assign
     // the value to var with possibly some transformation (e.g. Cocoa version
     // currently uses this to remove any accelerators from the button strings
@@ -309,15 +257,14 @@ private:
              m_ok,
              m_cancel;
 
-    wxDECLARE_NO_COPY_CLASS(wxMessageDialogWithCustomLabels);
+    wxDECLARE_NO_COPY_CLASS(wxMessageDialogBase);
 };
 
-#endif // ports needing wxMessageDialogWithCustomLabels
+#include "wx/generic/msgdlgg.h"
 
 #if defined(__WX_COMPILING_MSGDLGG_CPP__) || \
     defined(__WXUNIVERSAL__) || defined(__WXGPE__) || \
     (defined(__WXGTK__) && !defined(__WXGTK20__))
-    #include "wx/generic/msgdlgg.h"
 
     #define wxMessageDialog wxGenericMessageDialog
 #elif defined(__WXCOCOA__)
index 8fd4d7a4e38be85038d3ba363485cdb832956c11..3a91076877efab302b66541e16d282a7be4b0d32 100644 (file)
@@ -12,7 +12,7 @@
 #ifndef _WX_MSGBOXDLG_H_
 #define _WX_MSGBOXDLG_H_
 
-class WXDLLIMPEXP_CORE wxMessageDialog : public wxMessageDialogWithCustomLabels
+class WXDLLIMPEXP_CORE wxMessageDialog : public wxMessageDialogBase
 {
 public:
     wxMessageDialog(wxWindow *parent,
@@ -20,7 +20,7 @@ public:
                     const wxString& caption = wxMessageBoxCaptionStr,
                     long style = wxOK|wxCENTRE,
                     const wxPoint& WXUNUSED(pos) = wxDefaultPosition)
-        : wxMessageDialogWithCustomLabels(parent, message, caption, style)
+        : wxMessageDialogBase(parent, message, caption, style)
     {
         m_hook = NULL;
     }
@@ -55,11 +55,16 @@ private:
     // offset all buttons starting from the first one given by dx to the right
     void OffsetButtonsStartingFrom(int first, int dx);
 
+    // used by ShowModal() to display a message box when task dialogs
+    // aren't available.
+    int ShowMessageBox();
+
+    // used by ShowModal() to display a task dialog.
+    int ShowTaskDialog();
 
     WXHANDLE m_hook; // HHOOK used to position the message box
 
-    DECLARE_DYNAMIC_CLASS(wxMessageDialog)
-    wxDECLARE_NO_COPY_CLASS(wxMessageDialog);
+    wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxMessageDialog);
 };
 
 
diff --git a/include/wx/msw/private/msgdlg.h b/include/wx/msw/private/msgdlg.h
new file mode 100644 (file)
index 0000000..5df01fc
--- /dev/null
@@ -0,0 +1,91 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        wx/msw/private/msgdlg.h
+// Purpose:     helper functions used with native message dialog
+// Author:      Rickard Westerlund
+// Created:     2010-07-12
+// RCS-ID:      $Id$
+// Copyright:   (c) 2010 wxWidgets team
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_MSW_PRIVATE_MSGDLG_H_
+#define _WX_MSW_PRIVATE_MSGDLG_H_
+
+#include "wx/msw/wrapcctl.h"
+#include "wx/scopedarray.h"
+
+// Macro to help identify if task dialogs are available: we rely on
+// TD_WARNING_ICON being defined in the headers for this as this symbol is used
+// by the task dialogs only. Also notice that task dialogs are available for
+// Unicode applications only.
+#if defined(TD_WARNING_ICON) && wxUSE_UNICODE
+    #define wxHAS_MSW_TASKDIALOG
+#endif
+
+// Provides methods for creating a task dialog.
+namespace wxMSWMessageDialog
+{
+
+#ifdef wxHAS_MSW_TASKDIALOG
+    class wxMSWTaskDialogConfig
+    {
+    public:
+        wxMSWTaskDialogConfig()
+            : buttons(new TASKDIALOG_BUTTON[3]),
+              parent(NULL),
+              iconId(0),
+              style(0),
+              useCustomLabels(false)
+            { }
+
+        // initializes the object from a message dialog.
+        wxMSWTaskDialogConfig(const wxMessageDialogBase& dlg);
+
+        wxScopedArray<TASKDIALOG_BUTTON> buttons;
+        wxWindow *parent;
+        wxString caption;
+        wxString message;
+        wxString extendedMessage;
+        long iconId;
+        long style;
+        bool useCustomLabels;
+        wxString btnYesLabel;
+        wxString btnNoLabel;
+        wxString btnOKLabel;
+        wxString btnCancelLabel;
+
+        // Will create a task dialog with it's paremeters for it's creation
+        // stored in the provided TASKDIALOGCONFIG parameter.
+        // NOTE: The wxMSWTaskDialogConfig object needs to remain accessible
+        // during the subsequent call to TaskDialogIndirect().
+        void MSWCommonTaskDialogInit(TASKDIALOGCONFIG &tdc);
+
+        // Used by MSWCommonTaskDialogInit() to add a regular button or a
+        // button with a custom label if used.
+        void AddTaskDialogButton(TASKDIALOGCONFIG &tdc,
+                                 int btnCustomId,
+                                 int btnCommonId,
+                                 const wxString& customLabel);
+    }; // class wxMSWTaskDialogConfig
+
+
+    typedef HRESULT (WINAPI *TaskDialogIndirect_t)(const TASKDIALOGCONFIG *,
+                                                   int *, int *, BOOL *);
+
+    // Return the pointer to TaskDialogIndirect(). This should only be called
+    // if HasNativeTaskDialog() returned true and is normally guaranteed to
+    // succeed in this case.
+    TaskDialogIndirect_t GetTaskDialogIndirectFunc();
+#endif // wxHAS_MSW_TASKDIALOG
+
+
+    // Check if the task dialog is available: this simply checks the OS version
+    // as we know that it's only present in Vista and later.
+    bool HasNativeTaskDialog();
+
+    // Translates standard MSW button IDs like IDCANCEL into an equivalent
+    // wx constant such as wxCANCEL.
+    int MSWTranslateReturnCode(int msAns);
+}; // namespace wxMSWMessageDialog
+
+#endif // _WX_MSW_PRIVATE_MSGDLG_H_
index a3f7a4dcf8bd82f379d959fad5f61f30f8a05a87..cf104e1db2e3039dd71fd37d2ff866af87d99612 100644 (file)
@@ -13,7 +13,7 @@
 #ifndef _WX_MSGBOXDLG_H_
 #define _WX_MSGBOXDLG_H_
 
-class WXDLLIMPEXP_CORE wxMessageDialog : public wxMessageDialogWithCustomLabels
+class WXDLLIMPEXP_CORE wxMessageDialog : public wxMessageDialogBase
 {
 public:
     wxMessageDialog(wxWindow *parent,
index 850e276501057f7291cef64cf9e4ea7ee60efcf3..a746e68a7828c4d2636d4d35c8184da0e4830746 100644 (file)
@@ -47,6 +47,8 @@
     @style{wxICON_QUESTION}
         Displays a question mark symbol. This icon is automatically used
         with @c wxYES_NO so it's usually unnecessary to specify it explicitly.
+        This style is not supported for MSW task dialogs, as question icons do
+        not follow the guidelines. No icon will be displayed in this case.
     @style{wxICON_INFORMATION}
         Displays an information symbol. This icon is used by default if
         @c wxYES_NO is not given so it is usually unnecessary to specify it
@@ -56,7 +58,9 @@
         just its parent (currently implemented only under MSW and GTK).
     @style{wxCENTRE}
         Centre the message box on its parent or on the screen if parent is not
-        specified (currently only implemented under MSW).
+        specified.
+        Setting this style under MSW makes no differences as the dialog is
+        always centered on the parent.
     @endStyleTable
 
     @library{wxcore}
index d908ebb47f08d0e03efe6bf3e9bda05fb2a6365c..f80e1955902a2dcf4d4bfd713499b2d520ce2482 100644 (file)
@@ -16,7 +16,7 @@
 #pragma hdrstop
 #endif
 
-#if wxUSE_MSGDLG && (!defined(__WXGTK20__) || defined(__WXUNIVERSAL__) || defined(__WXGPE__))
+#if wxUSE_MSGDLG
 
 #ifndef WX_PRECOMP
     #include "wx/utils.h"
@@ -103,7 +103,11 @@ void wxGenericMessageDialog::DoCreateMsgdialog()
     topsizer->Add( icon_text, 1, wxCENTER | wxLEFT|wxRIGHT|wxTOP, 10 );
 #endif // wxUSE_STATTEXT
 
-    // 3) buttons
+    // 3) optional checkbox and detailed text
+    AddMessageDialogCheckBox( topsizer );
+    AddMessageDialogDetails( topsizer );
+
+    // 4) buttons
     int center_flag = wxEXPAND;
     if (m_dialogStyle & wxYES_NO)
         center_flag = wxALIGN_CENTRE;
@@ -162,4 +166,4 @@ int wxGenericMessageDialog::ShowModal()
     return wxMessageDialogBase::ShowModal();
 }
 
-#endif // wxUSE_MSGDLG && !defined(__WXGTK20__)
+#endif // wxUSE_MSGDLG
index dc24565e391852c931f817fb7ccb43a1a40c77e7..5275bac3feaaaf2ca5cae270c7230c2bf8cb9c00 100644 (file)
@@ -44,7 +44,7 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent,
                                  const wxString& caption,
                                  long style,
                                  const wxPoint& WXUNUSED(pos))
-               : wxMessageDialogWithCustomLabels
+               : wxMessageDialogBase
                  (
                     GetParentForModalDialog(parent, style),
                     message,
@@ -79,7 +79,7 @@ void wxMessageDialog::DoSetCustomLabel(wxString& var, const ButtonLabel& label)
     int stockId = label.GetStockId();
     if ( stockId == wxID_NONE )
     {
-        wxMessageDialogWithCustomLabels::DoSetCustomLabel(var, label);
+        wxMessageDialogBase::DoSetCustomLabel(var, label);
         var = wxConvertMnemonicsToGTK(var);
     }
     else // stock label
index b25e7b84e0c6d0544df7a864ea917f7805478813..50191c6f77c09a6ef4ddb47da755d5288cbf3942 100644 (file)
@@ -18,7 +18,7 @@
 
 #if wxUSE_MSGDLG
 
-#include "wx/msgdlg.h"
+#include "wx/ptr_scpd.h"
 
 // there is no hook support under CE so we can't use the code for message box
 // positioning there
     #endif
 #endif
 
+#include "wx/dynlib.h"
 #include "wx/msw/private.h"
 #include "wx/msw/private/button.h"
 #include "wx/msw/private/metrics.h"
+#include "wx/msw/private/msgdlg.h"
+#include "wx/msgdlg.h"
 
 #if wxUSE_MSGBOX_HOOK
     #include "wx/fontutil.h"
@@ -53,6 +56,8 @@
     #include "wx/msw/wince/missing.h"
 #endif
 
+using namespace wxMSWMessageDialog;
+
 IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
 
 #if wxUSE_MSGBOX_HOOK
@@ -430,7 +435,7 @@ wxFont wxMessageDialog::GetMessageFont()
     return wxNativeFontInfo(ncm.lfMessageFont);
 }
 
-int wxMessageDialog::ShowModal()
+int wxMessageDialog::ShowMessageBox()
 {
     if ( !wxTheApp->GetTopWindow() )
     {
@@ -564,11 +569,194 @@ int wxMessageDialog::ShowModal()
 
     // do show the dialog
     int msAns = MessageBox(hWnd, message.wx_str(), m_caption.wx_str(), msStyle);
+
+    return MSWTranslateReturnCode(msAns);
+}
+
+int wxMessageDialog::ShowTaskDialog()
+{
+#ifdef wxHAS_MSW_TASKDIALOG
+    TaskDialogIndirect_t taskDialogIndirect = GetTaskDialogIndirectFunc();
+    if ( !taskDialogIndirect )
+        return wxID_CANCEL;
+
+    WinStruct<TASKDIALOGCONFIG> tdc;
+    wxMSWTaskDialogConfig wxTdc( *this );
+    wxTdc.MSWCommonTaskDialogInit( tdc );
+
+    int msAns;
+    HRESULT hr = taskDialogIndirect( &tdc, &msAns, NULL, NULL );
+    if ( FAILED(hr) )
+    {
+        wxLogApiError( "TaskDialogIndirect", hr );
+        return wxID_CANCEL;
+    }
+
+    return MSWTranslateReturnCode( msAns );
+#else
+    wxFAIL_MSG( "Task dialogs are unavailable." );
+
+    return wxID_CANCEL;
+#endif // wxHAS_MSW_TASKDIALOG
+}
+
+
+
+int wxMessageDialog::ShowModal()
+{
+    if ( HasNativeTaskDialog() )
+        return ShowTaskDialog();
+
+    return ShowMessageBox();
+}
+
+// ----------------------------------------------------------------------------
+// Helpers of the wxMSWMessageDialog namespace
+// ----------------------------------------------------------------------------
+
+#ifdef wxHAS_MSW_TASKDIALOG
+
+wxMSWTaskDialogConfig::wxMSWTaskDialogConfig(const wxMessageDialogBase& dlg)
+                     : buttons(new TASKDIALOG_BUTTON[3])
+{
+    parent = dlg.GetParentForModalDialog();
+    caption = dlg.GetCaption();
+    message = dlg.GetMessage();
+    extendedMessage = dlg.GetExtendedMessage();
+    iconId = dlg.GetEffectiveIcon();
+    style = dlg.GetMessageDialogStyle();
+    useCustomLabels = dlg.HasCustomLabels();
+    btnYesLabel = dlg.GetYesLabel();
+    btnNoLabel = dlg.GetNoLabel();
+    btnOKLabel = dlg.GetOKLabel();
+    btnCancelLabel = dlg.GetCancelLabel();
+}
+
+void wxMSWTaskDialogConfig::MSWCommonTaskDialogInit(TASKDIALOGCONFIG &tdc)
+{
+    tdc.dwFlags = TDF_EXPAND_FOOTER_AREA | TDF_POSITION_RELATIVE_TO_WINDOW;
+    tdc.hInstance = wxGetInstance();
+    tdc.pszWindowTitle = caption.wx_str();
+
+    // use the top level window as parent if none specified
+    tdc.hwndParent = parent ? GetHwndOf(parent) : NULL;
+
+    if ( wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft )
+        tdc.dwFlags |= TDF_RTL_LAYOUT;
+    tdc.pszMainInstruction = message.wx_str();
+    tdc.pszContent = extendedMessage.wx_str();
+
+    // set an icon to be used, if possible
+    switch ( iconId )
+    {
+        case wxICON_ERROR:
+            tdc.pszMainIcon = TD_ERROR_ICON;
+            break;
+
+        case wxICON_WARNING:
+            tdc.pszMainIcon = TD_WARNING_ICON;
+            break;
+
+        case wxICON_INFORMATION:
+            tdc.pszMainIcon = TD_INFORMATION_ICON;
+            break;
+    }
+
+    // custom label button array that can hold all buttons in use
+    tdc.pButtons = buttons.get();
+
+    if ( style & wxYES_NO )
+    {
+        AddTaskDialogButton(tdc, IDYES, TDCBF_YES_BUTTON, btnYesLabel);
+        AddTaskDialogButton(tdc, IDNO,  TDCBF_NO_BUTTON,  btnNoLabel);
+
+        if (style & wxCANCEL)
+            AddTaskDialogButton(tdc, IDCANCEL,
+                                TDCBF_CANCEL_BUTTON, btnCancelLabel);
+
+        if ( style & wxNO_DEFAULT )
+            tdc.nDefaultButton = IDNO;
+        else if ( style & wxCANCEL_DEFAULT )
+            tdc.nDefaultButton = IDCANCEL;
+    }
+    else // without Yes/No we're going to have an OK button
+    {
+        AddTaskDialogButton(tdc, IDOK, TDCBF_OK_BUTTON, btnOKLabel);
+
+        if ( style & wxCANCEL )
+        {
+            AddTaskDialogButton(tdc, IDCANCEL,
+                                TDCBF_CANCEL_BUTTON, btnCancelLabel);
+
+            if ( style & wxCANCEL_DEFAULT )
+                tdc.nDefaultButton = IDCANCEL;
+        }
+    }
+}
+
+void wxMSWTaskDialogConfig::AddTaskDialogButton(TASKDIALOGCONFIG &tdc,
+                                                int btnCustomId,
+                                                int btnCommonId,
+                                                const wxString& customLabel)
+{
+    if ( useCustomLabels )
+    {
+        // use custom buttons to implement custom labels
+        TASKDIALOG_BUTTON &tdBtn = buttons[tdc.cButtons];
+
+        tdBtn.nButtonID = btnCustomId;
+        tdBtn.pszButtonText = customLabel.wx_str();
+        tdc.cButtons++;
+    }
+    else
+    {
+        tdc.dwCommonButtons |= btnCommonId;
+    }
+}
+
+// Task dialog can be used from different threads (and wxProgressDialog always
+// uses it from another thread in fact) so protect access to the static
+// variable below with a critical section.
+wxCRIT_SECT_DECLARE(gs_csTaskDialogIndirect);
+
+TaskDialogIndirect_t wxMSWMessageDialog::GetTaskDialogIndirectFunc()
+{
+    static TaskDialogIndirect_t s_TaskDialogIndirect = NULL;
+
+    wxCRIT_SECT_LOCKER(lock, gs_csTaskDialogIndirect);
+
+    if ( !s_TaskDialogIndirect )
+    {
+        wxLoadedDLL dllComCtl32("comctl32.dll");
+        wxDL_INIT_FUNC(s_, TaskDialogIndirect, dllComCtl32);
+
+        // We must always succeed as this code is only executed under Vista and
+        // later which must have task dialog support.
+        wxASSERT_MSG( s_TaskDialogIndirect,
+                      "Task dialog support unexpectedly not available" );
+    }
+
+    return s_TaskDialogIndirect;
+}
+
+#endif // wxHAS_MSW_TASKDIALOG
+
+bool wxMSWMessageDialog::HasNativeTaskDialog()
+{
+#ifdef wxHAS_MSW_TASKDIALOG
+    return wxGetWinVersion() >= wxWinVersion_6;
+#else
+    return false;
+#endif
+}
+
+int wxMSWMessageDialog::MSWTranslateReturnCode(int msAns)
+{
     int ans;
     switch (msAns)
     {
         default:
-            wxFAIL_MSG(wxT("unexpected ::MessageBox() return code"));
+            wxFAIL_MSG(wxT("unexpected return code"));
             // fall through
 
         case IDCANCEL:
@@ -584,6 +772,7 @@ int wxMessageDialog::ShowModal()
             ans = wxID_NO;
             break;
     }
+
     return ans;
 }
 
index bc410c3c037e185b3fa3b4e9184463ad3c165d93..49b5bb1f5ad343e05af90be69f52cd091f7a7f1a 100644 (file)
@@ -30,7 +30,7 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent,
                                  const wxString& caption,
                                  long style,
                                  const wxPoint& WXUNUSED(pos))
-               : wxMessageDialogWithCustomLabels(parent, message, caption, style)
+               : wxMessageDialogBase(parent, message, caption, style)
 {
 }
 
index 830d855ccc0c3e1fe77022ba552954fe482df520..042a302c0805dd89b45740a02d73dbaa78fdde2b 100644 (file)
@@ -47,7 +47,7 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent,
                                  const wxString& caption,
                                  long style,
                                  const wxPoint& WXUNUSED(pos))
-               : wxMessageDialogWithCustomLabels(parent, message, caption, style)
+               : wxMessageDialogBase(parent, message, caption, style)
 {
 }
 
index e7598c74a88249725580498a84c7d0ef2eef9675..e3aff16cc90342523c0feaacc8589b4d16c91435 100644 (file)
@@ -30,7 +30,7 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent,
                                  const wxString& caption,
                                  long style,
                                  const wxPoint& WXUNUSED(pos))
-               : wxMessageDialogWithCustomLabels(parent, message, caption, style)
+               : wxMessageDialogBase(parent, message, caption, style)
 {
 }