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
// aren't available.
int ShowMessageBox();
// 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
WXHANDLE m_hook; // HHOOK used to position the message box
return MSWTranslateReturnCode(msAns);
}
return MSWTranslateReturnCode(msAns);
}
-int wxMessageDialog::ShowTaskDialog()
+int wxMessageDialog::ShowModal()
{
#ifdef wxHAS_MSW_TASKDIALOG
{
#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) )
+ if ( HasNativeTaskDialog() )
- wxLogApiError( "TaskDialogIndirect", hr );
- return wxID_CANCEL;
- }
-
- return MSWTranslateReturnCode( msAns );
-#else
- wxFAIL_MSG( "Task dialogs are unavailable." );
-
- return wxID_CANCEL;
-#endif // wxHAS_MSW_TASKDIALOG
-}
+ TaskDialogIndirect_t taskDialogIndirect = GetTaskDialogIndirectFunc();
+ wxCHECK_MSG( taskDialogIndirect, wxID_CANCEL, wxS("no task dialog?") );
+ 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;
+ }
-int wxMessageDialog::ShowModal()
-{
- if ( HasNativeTaskDialog() )
- return ShowTaskDialog();
+ return MSWTranslateReturnCode( msAns );
+ }
+#endif // wxHAS_MSW_TASKDIALOG
return ShowMessageBox();
}
return ShowMessageBox();
}
TaskDialogIndirect_t wxMSWMessageDialog::GetTaskDialogIndirectFunc()
{
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<TaskDialogIndirect_t>(-1);
+ static TaskDialogIndirect_t s_TaskDialogIndirect = INVALID_TASKDIALOG_FUNC;
wxCRIT_SECT_LOCKER(lock, gs_csTaskDialogIndirect);
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);
{
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;
}
return s_TaskDialogIndirect;
bool wxMSWMessageDialog::HasNativeTaskDialog()
{
#ifdef wxHAS_MSW_TASKDIALOG
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
+
}
int wxMSWMessageDialog::MSWTranslateReturnCode(int msAns)
}
int wxMSWMessageDialog::MSWTranslateReturnCode(int msAns)