X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6757b5e31cb48dd909754fdd5ceb5947585b76e1..f910a887bbaf6d1bc81e7ba45c54c621f8b33cd2:/src/msw/dialog.cpp diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index 948fd5bc80..9563732e25 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -41,6 +41,7 @@ #include "wx/msw/private.h" #include "wx/log.h" #include "wx/evtloop.h" +#include "wx/ptr_scpd.h" #if wxUSE_COMMON_DIALOGS && !defined(__WXMICROWIN__) #include @@ -135,38 +136,29 @@ END_EVENT_TABLE() // wxDialogModalData // ---------------------------------------------------------------------------- -// this is simply a container for wxEventLoop and wxWindowDisabler which allows -// to have a single opaque pointer in wxDialog itself +// this is simply a container for any data we need to implement modality which +// allows us to avoid changing wxDialog each time the implementation changes class wxDialogModalData { public: - wxDialogModalData() { m_windowDisabler = NULL; } + wxDialogModalData(wxDialog *dialog) : m_evtLoop(dialog) { } - void RunLoop(wxDialog *dialog) + void RunLoop() { - m_windowDisabler = new wxWindowDisabler(dialog); - m_evtLoop.Run(); } void ExitLoop() { - delete m_windowDisabler; - m_windowDisabler = NULL; - m_evtLoop.Exit(); } - ~wxDialogModalData() - { - wxASSERT_MSG( !m_windowDisabler, _T("forgot to call ExitLoop?") ); - } - private: - wxEventLoop m_evtLoop; - wxWindowDisabler *m_windowDisabler; + wxModalEventLoop m_evtLoop; }; +wxDEFINE_TIED_SCOPED_PTR_TYPE(wxDialogModalData); + // ============================================================================ // implementation // ============================================================================ @@ -178,11 +170,10 @@ private: void wxDialog::Init() { m_oldFocus = (wxWindow *)NULL; - m_isShown = FALSE; - m_modalData = NULL; - + m_endModalCalled = FALSE; + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); } @@ -206,8 +197,8 @@ bool wxDialog::Create(wxWindow *parent, if ( !wxTopLevelWindow::Create(parent, id, title, pos, size, style, name) ) return FALSE; - - SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + if (!m_hasFont) + SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); return TRUE; } @@ -325,19 +316,12 @@ void wxDialog::DoShowModal() hwndOldFocus = GetHwndOf(parent); } - // before entering the modal loop, reset the "is in OnIdle()" flag (see - // comment in app.cpp) - extern bool wxIsInOnIdleFlag; - bool wasInOnIdle = wxIsInOnIdleFlag; - wxIsInOnIdleFlag = FALSE; - // enter the modal loop - m_modalData = new wxDialogModalData; - m_modalData->RunLoop(this); - delete m_modalData; - m_modalData = NULL; - - wxIsInOnIdleFlag = wasInOnIdle; + { + wxDialogModalDataTiedPtr modalData(&m_modalData, + new wxDialogModalData(this)); + modalData->RunLoop(); + } // and restore focus // Note that this code MUST NOT access the dialog object's data @@ -384,7 +368,10 @@ bool wxDialog::Show(bool show) InitDialog(); } - if ( show && IsModal() ) + // EndModal may have been called from InitDialog handler, + // which would cause an infinite loop if we didn't take it + // into account + if ( show && IsModal() && !m_endModalCalled ) { // modal dialog needs a parent window, so try to find one if ( !GetParent() ) @@ -406,6 +393,7 @@ void wxDialog::Raise() // a special version for Show(TRUE) for modal dialogs which returns return code int wxDialog::ShowModal() { + m_endModalCalled = FALSE; if ( !IsModal() ) { SetModal(TRUE); @@ -420,6 +408,7 @@ int wxDialog::ShowModal() // dialogs and should work for both of them void wxDialog::EndModal(int retCode) { + m_endModalCalled = TRUE; SetReturnCode(retCode); Show(FALSE); @@ -517,7 +506,7 @@ long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) // creates flicker but at least doesn't show garbage on the screen rc = wxWindow::MSWWindowProc(message, wParam, lParam); processed = TRUE; - if ( !HasFlag(wxNO_FULL_REPAINT_ON_RESIZE) ) + if ( HasFlag(wxFULL_REPAINT_ON_RESIZE) ) { ::InvalidateRect(GetHwnd(), NULL, FALSE /* erase bg */); }