Provide a task-dialog based wxMSW wxMessageDialog implementation.
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
This commit is contained in:
@@ -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
|
||||
@@ -38,9 +38,12 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user