Prevent constant size changes in native MSW wxProgressDialog
MSW implementation of wxProgressDialog adjusted the dialog size to the size of the message shown in it on each update, resulting in visually unpleasant constant jumping around (this is the same problem that we used to have in wxGenericProgressDialog long time ago, see #10624). Minimize this by using TDM_UPDATE_ELEMENT_TEXT instead of TDM_SET_ELEMENT_TEXT for changing the element text. This still increases the dialog size if the new element text is longer than the old value, but at least doesn't shrink it back if it is shorter, which is already quite an improvement. Notice that this change requires using TDF_EXPAND_FOOTER_AREA style, as otherwise the expanded information can't be updated without a re-layout. But this doesn't seem to be a big loss and it's not really clear why did we explicitly clear this flag before anyhow. Update the dialogs sample to make it easy to test for this behaviour and the documentation to mention MSW version peculiarities.
This commit is contained in:
parent
6d2f903a48
commit
0736bdfb28
@ -194,7 +194,9 @@ public:
|
||||
|
||||
Notice that you may want to call Fit() to change the dialog size to
|
||||
conform to the length of the new message if desired. The dialog does
|
||||
not do this automatically.
|
||||
not do this automatically, except for the native MSW implementation
|
||||
which does increase the dialog size if necessary (but still doesn't
|
||||
shrink it back even if the text becomes shorter).
|
||||
|
||||
@param value
|
||||
The new value of the progress meter. It should be less than or equal to
|
||||
|
@ -349,7 +349,20 @@ bool MyApp::OnInit()
|
||||
);
|
||||
for ( int i = 0; i <= PROGRESS_COUNT; i++ )
|
||||
{
|
||||
if ( !dlg.Update(i) )
|
||||
wxString msg;
|
||||
switch ( i )
|
||||
{
|
||||
case 15:
|
||||
msg = "And the same dialog but with a very, very, very long"
|
||||
" message, just to test how it appears in this case.";
|
||||
break;
|
||||
|
||||
case 30:
|
||||
msg = "Back to brevity";
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !dlg.Update(i, msg) )
|
||||
break;
|
||||
|
||||
wxMilliSleep(50);
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
m_value = 0;
|
||||
m_progressBarMarquee = false;
|
||||
m_skipped = false;
|
||||
m_msgChangeElementText = TDM_SET_ELEMENT_TEXT;
|
||||
m_notifications = 0;
|
||||
m_parent = NULL;
|
||||
}
|
||||
@ -105,6 +106,14 @@ public:
|
||||
bool m_progressBarMarquee;
|
||||
bool m_skipped;
|
||||
|
||||
// The task dialog message to use for changing the text of its elements:
|
||||
// it's TDM_SET_ELEMENT_TEXT initially as this message should be used to
|
||||
// let the dialog adjust itself to the size of its elements, but
|
||||
// TDM_UPDATE_ELEMENT_TEXT later to prevent the dialog from performing a
|
||||
// layout on each update, which is annoying as it can result in its size
|
||||
// constantly changing.
|
||||
int m_msgChangeElementText;
|
||||
|
||||
// Bit field that indicates fields that have been modified by the
|
||||
// main thread so the task dialog runner knows what to update.
|
||||
int m_notifications;
|
||||
@ -260,14 +269,27 @@ void PerformNotificationUpdates(HWND hwnd,
|
||||
}
|
||||
|
||||
::SendMessage( hwnd,
|
||||
TDM_SET_ELEMENT_TEXT,
|
||||
sharedData->m_msgChangeElementText,
|
||||
TDE_MAIN_INSTRUCTION,
|
||||
wxMSW_CONV_LPARAM(title) );
|
||||
|
||||
::SendMessage( hwnd,
|
||||
TDM_SET_ELEMENT_TEXT,
|
||||
sharedData->m_msgChangeElementText,
|
||||
TDE_CONTENT,
|
||||
wxMSW_CONV_LPARAM(body) );
|
||||
|
||||
// After using TDM_SET_ELEMENT_TEXT once, we don't want to use it for
|
||||
// the subsequent updates as it could result in dialog size changing
|
||||
// unexpectedly, so reset it (which does nothing if we had already done
|
||||
// it, of course, but it's not a problem).
|
||||
//
|
||||
// Notice that, contrary to its documentation, even using this message
|
||||
// still increases the dialog size if the new text is longer (at least
|
||||
// under Windows 7), but it doesn't shrink back if the text becomes
|
||||
// shorter later and stays at the bigger size which is still a big gain
|
||||
// as it prevents jumping back and forth between the smaller and larger
|
||||
// sizes.
|
||||
sharedData->m_msgChangeElementText = TDM_UPDATE_ELEMENT_TEXT;
|
||||
}
|
||||
|
||||
if ( sharedData->m_notifications & wxSPDD_EXPINFO_CHANGED )
|
||||
@ -276,8 +298,15 @@ void PerformNotificationUpdates(HWND hwnd,
|
||||
sharedData->m_expandedInformation;
|
||||
if ( !expandedInformation.empty() )
|
||||
{
|
||||
// Here we never need to use TDM_SET_ELEMENT_TEXT as the size of
|
||||
// the expanded information doesn't change drastically.
|
||||
//
|
||||
// Notice that TDM_UPDATE_ELEMENT_TEXT for this element only works
|
||||
// when using TDF_EXPAND_FOOTER_AREA, as we do. Without this flag,
|
||||
// only TDM_SET_ELEMENT_TEXT could be used as otherwise the dialog
|
||||
// layout becomes completely mangled (at least under Windows 7).
|
||||
::SendMessage( hwnd,
|
||||
TDM_SET_ELEMENT_TEXT,
|
||||
TDM_UPDATE_ELEMENT_TEXT,
|
||||
TDE_EXPANDED_INFORMATION,
|
||||
wxMSW_CONV_LPARAM(expandedInformation) );
|
||||
}
|
||||
@ -777,8 +806,9 @@ bool wxProgressDialog::Show(bool show)
|
||||
wxPD_ESTIMATED_TIME |
|
||||
wxPD_REMAINING_TIME) )
|
||||
{
|
||||
// Use a non-empty string just to have the collapsible pane shown.
|
||||
m_sharedData->m_expandedInformation = " ";
|
||||
// Set the expanded information field from the beginning to avoid
|
||||
// having to re-layout the dialog later when it changes.
|
||||
UpdateExpandedInformation(0);
|
||||
}
|
||||
|
||||
// Do launch the thread.
|
||||
@ -887,9 +917,6 @@ void* wxProgressDialogTaskRunner::Entry()
|
||||
tdc.pfCallback = TaskDialogCallbackProc;
|
||||
tdc.lpCallbackData = (LONG_PTR) &m_sharedData;
|
||||
|
||||
// Undo some of the effects of MSWCommonTaskDialogInit().
|
||||
tdc.dwFlags &= ~TDF_EXPAND_FOOTER_AREA; // Expand in content area.
|
||||
|
||||
if ( m_sharedData.m_style & wxPD_CAN_SKIP )
|
||||
wxTdc.AddTaskDialogButton( tdc, Id_SkipBtn, 0, _("Skip") );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user