Allow setting position of wxProgressDialog (wxMSW)

Position of wxProgressDialog cannot be changed directly because the dialog is created in another thread and may exist when SetPosition() is called. New position has be stored in the data structure used to share data between the main thread and the task dialog runner and the real update is done during the cyclic refresh in the dialog thread.

Closes #13546.
This commit is contained in:
Artur Wieczorek 2017-10-05 16:22:15 +02:00
parent 961a1c2b39
commit 1ef1f8fda6
3 changed files with 67 additions and 0 deletions

View File

@ -211,6 +211,7 @@ wxMSW:
- Fix wxTextCtrl::XYToPosition() and PositionToXY().
- Fix updating radio groups when non-radio item is inserted to wxMenu.
- Fix autoselecting the contents of wxTextCtrl with wxWANTS_CHARS style.
- Implement SetIcon(), SetPosition(), GetPosition() for native wxProgressDialog.
wxOSX:

View File

@ -42,6 +42,8 @@ public:
virtual wxString GetTitle() const wxOVERRIDE;
virtual void SetIcons(const wxIconBundle& icons) wxOVERRIDE;
virtual void DoMoveWindow(int x, int y, int width, int height) wxOVERRIDE;
virtual void DoGetPosition(int *x, int *y) const wxOVERRIDE;
virtual bool Show( bool show = true ) wxOVERRIDE;

View File

@ -61,6 +61,7 @@ const int wxSPDD_DISABLE_ABORT = 0x0200;
const int wxSPDD_FINISHED = 0x0400;
const int wxSPDD_DESTROYED = 0x0800;
const int wxSPDD_ICON_CHANGED = 0x1000;
const int wxSPDD_WINDOW_MOVED = 0x2000;
const int Id_SkipBtn = wxID_HIGHEST + 1;
@ -98,6 +99,7 @@ public:
unsigned long m_timeStop;
wxIcon m_iconSmall;
wxIcon m_iconBig;
wxPoint m_winPosition;
wxProgressDialog::State m_state;
bool m_progressBarMarquee;
@ -222,6 +224,13 @@ void PerformNotificationUpdates(HWND hwnd,
::SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)GetHiconOf(sharedData->m_iconBig));
}
if ( sharedData->m_notifications & wxSPDD_WINDOW_MOVED )
{
::SetWindowPos(hwnd, NULL, sharedData->m_winPosition.x, sharedData->m_winPosition.y,
-1, -1, // ignored
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
}
if ( sharedData->m_notifications & wxSPDD_MESSAGE_CHANGED )
{
// Split the message in the title string and the rest if it has
@ -687,6 +696,48 @@ void wxProgressDialog::SetIcons(const wxIconBundle& icons)
wxGenericProgressDialog::SetIcons(icons);
}
void wxProgressDialog::DoMoveWindow(int x, int y, int width, int height)
{
#ifdef wxHAS_MSW_TASKDIALOG
if ( HasNativeTaskDialog() )
{
if ( m_sharedData )
{
wxCriticalSectionLocker locker(m_sharedData->m_cs);
m_sharedData->m_winPosition = wxPoint(x, y);
m_sharedData->m_notifications |= wxSPDD_WINDOW_MOVED;
}
return;
}
#endif // wxHAS_MSW_TASKDIALOG
wxGenericProgressDialog::DoMoveWindow(x, y, width, height);
}
void wxProgressDialog::DoGetPosition(int *x, int *y) const
{
#ifdef wxHAS_MSW_TASKDIALOG
if ( HasNativeTaskDialog() )
{
wxPoint pos;
{
wxCriticalSectionLocker locker(m_sharedData->m_cs);
m_sharedData->m_state = m_state;
pos = m_sharedData->m_winPosition;
}
if (x)
*x = pos.x;
if (y)
*y = pos.y;
return;
}
#endif // wxHAS_MSW_TASKDIALOG
wxGenericProgressDialog::DoGetPosition(x, y);
}
bool wxProgressDialog::Show(bool show)
{
#ifdef wxHAS_MSW_TASKDIALOG
@ -917,6 +968,14 @@ wxProgressDialogTaskRunner::TaskDialogCallbackProc
SWP_NOZORDER);
}
// Store current position for the main thread use
// if no position update is pending.
if ( !(sharedData->m_notifications & wxSPDD_WINDOW_MOVED) )
{
RECT r = wxGetWindowRect(hwnd);
sharedData->m_winPosition = wxPoint(r.left, r.top);
}
// If we can't be aborted, the "Close" button will only be enabled
// when the progress ends (and not even then with wxPD_AUTO_HIDE).
if ( !(sharedData->m_style & wxPD_CAN_ABORT) )
@ -986,6 +1045,11 @@ wxProgressDialogTaskRunner::TaskDialogCallbackProc
}
sharedData->m_notifications = 0;
{
// Update current position for the main thread use.
RECT r = wxGetWindowRect(hwnd);
sharedData->m_winPosition = wxPoint(r.left, r.top);
}
return TRUE;
}