]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/msgdlg.cpp
Fixed wxscintilla compilation for wxDFB.
[wxWidgets.git] / src / msw / msgdlg.cpp
index feddca75214a8eba9c69b9d419456d73ad06be27..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() )
     {
@@ -443,8 +448,7 @@ int wxMessageDialog::ShowModal()
     }
 
     // use the top level window as parent if none specified
-    if ( !m_parent )
-        m_parent = GetParentForModalDialog();
+    m_parent = GetParentForModalDialog();
     HWND hWnd = m_parent ? GetHwndOf(m_parent) : NULL;
 
 #if wxUSE_INTL
@@ -565,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:
@@ -585,6 +772,7 @@ int wxMessageDialog::ShowModal()
             ans = wxID_NO;
             break;
     }
+
     return ans;
 }