From 5b1985a920a3e3fb457192d4bee7ea89a72a974a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 15 Oct 2010 23:46:19 +0000 Subject: [PATCH] Check for task dialog availability even under Vista and later. Task dialogs are not always available under Vista and later Windows versions because we might not be using the right (i.e. 6+) version of comctl32.dll. Improve the check for task dialog availability and fall back to the classic message box if we can't use it. Closes #12553. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65816 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/msgdlg.h | 2 -- src/msw/msgdlg.cpp | 75 +++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 42 deletions(-) diff --git a/include/wx/msw/msgdlg.h b/include/wx/msw/msgdlg.h index 3a91076877..784d339b61 100644 --- a/include/wx/msw/msgdlg.h +++ b/include/wx/msw/msgdlg.h @@ -59,8 +59,6 @@ private: // 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 diff --git a/src/msw/msgdlg.cpp b/src/msw/msgdlg.cpp index ce8d4eafe5..f6057f7361 100644 --- a/src/msw/msgdlg.cpp +++ b/src/msw/msgdlg.cpp @@ -573,39 +573,29 @@ int wxMessageDialog::ShowMessageBox() return MSWTranslateReturnCode(msAns); } -int wxMessageDialog::ShowTaskDialog() -{ -#ifdef wxHAS_MSW_TASKDIALOG - TaskDialogIndirect_t taskDialogIndirect = GetTaskDialogIndirectFunc(); - if ( !taskDialogIndirect ) - return wxID_CANCEL; - - WinStruct 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() { +#ifdef wxHAS_MSW_TASKDIALOG if ( HasNativeTaskDialog() ) - return ShowTaskDialog(); + { + TaskDialogIndirect_t taskDialogIndirect = GetTaskDialogIndirectFunc(); + wxCHECK_MSG( taskDialogIndirect, wxID_CANCEL, wxS("no task dialog?") ); + + WinStruct 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 ); + } +#endif // wxHAS_MSW_TASKDIALOG return ShowMessageBox(); } @@ -758,19 +748,20 @@ wxCRIT_SECT_DECLARE(gs_csTaskDialogIndirect); TaskDialogIndirect_t wxMSWMessageDialog::GetTaskDialogIndirectFunc() { - static TaskDialogIndirect_t s_TaskDialogIndirect = NULL; + // Initialize the function pointer to an invalid value different from NULL + // to avoid reloading comctl32.dll and trying to resolve it every time + // we're called if task dialog is not available (notice that this may + // happen even under Vista+ if we don't use comctl32.dll v6). + static const TaskDialogIndirect_t + INVALID_TASKDIALOG_FUNC = reinterpret_cast(-1); + static TaskDialogIndirect_t s_TaskDialogIndirect = INVALID_TASKDIALOG_FUNC; wxCRIT_SECT_LOCKER(lock, gs_csTaskDialogIndirect); - if ( !s_TaskDialogIndirect ) + if ( s_TaskDialogIndirect == INVALID_TASKDIALOG_FUNC ) { 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; @@ -781,10 +772,14 @@ TaskDialogIndirect_t wxMSWMessageDialog::GetTaskDialogIndirectFunc() bool wxMSWMessageDialog::HasNativeTaskDialog() { #ifdef wxHAS_MSW_TASKDIALOG - return wxGetWinVersion() >= wxWinVersion_6; -#else + if ( wxGetWinVersion() >= wxWinVersion_6 ) + { + if ( wxMSWMessageDialog::GetTaskDialogIndirectFunc() ) + return true; + } +#endif // wxHAS_MSW_TASKDIALOG + return false; -#endif } int wxMSWMessageDialog::MSWTranslateReturnCode(int msAns)