X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2c66581eaae92045864aa8d0ab80fc27f8725e52..5778dedc92f6d31435aa1cda6846979a0e9ad35b:/src/msw/dialog.cpp?ds=inline diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index 64d7f61bc6..592c23a9bc 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -40,7 +40,7 @@ #include "wx/msw/private.h" #include "wx/evtloop.h" -#include "wx/ptr_scpd.h" +#include "wx/scopedptr.h" #if defined(__SMARTPHONE__) && defined(__WXWINCE__) #include "wx/msw/wince/resources.h" @@ -145,14 +145,14 @@ wxDEFINE_TIED_SCOPED_PTR_TYPE(wxDialogModalData) void wxDialog::Init() { - m_oldFocus = (wxWindow *)NULL; m_isShown = false; m_modalData = NULL; - m_endModalCalled = false; #if wxUSE_TOOLBAR && defined(__POCKETPC__) m_dialogToolBar = NULL; #endif +#if wxUSE_DIALOG_SIZEGRIP m_hGripper = 0; +#endif // wxUSE_DIALOG_SIZEGRIP } bool wxDialog::Create(wxWindow *parent, @@ -165,9 +165,6 @@ bool wxDialog::Create(wxWindow *parent, { SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG); - // save focus before doing anything which can potentially change it - m_oldFocus = FindFocus(); - // All dialogs should really have this style style |= wxTAB_TRAVERSAL; @@ -184,48 +181,33 @@ bool wxDialog::Create(wxWindow *parent, CreateToolBar(); #endif - if( HasFlag(wxRESIZE_BORDER) ) +#if wxUSE_DIALOG_SIZEGRIP + if ( HasFlag(wxRESIZE_BORDER) ) + { CreateGripper(); + Connect(wxEVT_CREATE, + wxWindowCreateEventHandler(wxDialog::OnWindowCreate)); + } +#endif // wxUSE_DIALOG_SIZEGRIP + return true; } wxDialog::~wxDialog() { - m_isBeingDeleted = true; - // this will also reenable all the other windows for a modal dialog Show(false); +#if wxUSE_DIALOG_SIZEGRIP DestroyGripper(); +#endif // wxUSE_DIALOG_SIZEGRIP } // ---------------------------------------------------------------------------- // showing the dialogs // ---------------------------------------------------------------------------- -wxWindow *wxDialog::FindSuitableParent() const -{ - // first try to use the currently active window - HWND hwndFg = ::GetForegroundWindow(); - wxWindow *parent = hwndFg ? wxFindWinFromHandle((WXHWND)hwndFg) - : NULL; - if ( !parent ) - { - // next try the main app window - parent = wxTheApp->GetTopWindow(); - } - - // finally, check if the parent we found is really suitable - if ( !parent || parent == (wxWindow *)this || !parent->IsShown() ) - { - // don't use this one - parent = NULL; - } - - return parent; -} - bool wxDialog::Show(bool show) { if ( show == IsShown() ) @@ -256,13 +238,15 @@ bool wxDialog::Show(bool show) if ( show ) { - // dialogs don't get WM_SIZE message after creation unlike most (all?) - // other windows and so could start their life non laid out correctly - // if we didn't call Layout() from here + // dialogs don't get WM_SIZE message from ::ShowWindow() for some + // reason so generate it ourselves for consistency with frames and + // dialogs in other ports // // NB: normally we should call it just the first time but doing it // every time is simpler than keeping a flag - Layout(); + const wxSize size = GetClientSize(); + ::SendMessage(GetHwnd(), WM_SIZE, + SIZE_RESTORED, MAKELPARAM(size.x, size.y)); } return true; @@ -276,56 +260,18 @@ void wxDialog::Raise() // show dialog modally int wxDialog::ShowModal() { - wxASSERT_MSG( !IsModal(), _T("wxDialog::ShowModal() reentered?") ); - - m_endModalCalled = false; + wxASSERT_MSG( !IsModal(), wxT("ShowModal() can't be called twice") ); Show(); // EndModal may have been called from InitDialog handler (called from - // inside Show()), which would cause an infinite loop if we didn't take it - // into account - if ( !m_endModalCalled ) + // inside Show()) and hidden the dialog back again + if ( IsShown() ) { - // modal dialog needs a parent window, so try to find one - wxWindow *parent = GetParent(); - if ( !parent ) - { - parent = FindSuitableParent(); - } - - // remember where the focus was - wxWindow *oldFocus = m_oldFocus; - if ( !oldFocus ) - { - // VZ: do we really want to do this? - oldFocus = parent; - } - - // We have to remember the HWND because we need to check - // the HWND still exists (oldFocus can be garbage when the dialog - // exits, if it has been destroyed) - HWND hwndOldFocus = oldFocus ? GetHwndOf(oldFocus) : NULL; - - // enter and run the modal loop - { - wxDialogModalDataTiedPtr modalData(&m_modalData, - new wxDialogModalData(this)); - modalData->RunLoop(); - } - - - // and restore focus - // Note that this code MUST NOT access the dialog object's data - // in case the object has been deleted (which will be the case - // for a modal dialog that has been destroyed before calling EndModal). - if ( oldFocus && (oldFocus != this) && ::IsWindow(hwndOldFocus)) - { - // This is likely to prove that the object still exists - if (wxFindWinFromHandle((WXHWND) hwndOldFocus) == oldFocus) - oldFocus->SetFocus(); - } + wxDialogModalDataTiedPtr modalData(&m_modalData, + new wxDialogModalData(this)); + modalData->RunLoop(); } return GetReturnCode(); @@ -333,9 +279,8 @@ int wxDialog::ShowModal() void wxDialog::EndModal(int retCode) { - wxASSERT_MSG( IsModal(), _T("EndModal() called for non modal dialog") ); + wxASSERT_MSG( IsModal(), wxT("EndModal() called for non modal dialog") ); - m_endModalCalled = true; SetReturnCode(retCode); Hide(); @@ -345,11 +290,13 @@ void wxDialog::EndModal(int retCode) // wxDialog gripper handling // ---------------------------------------------------------------------------- +#if wxUSE_DIALOG_SIZEGRIP + void wxDialog::SetWindowStyleFlag(long style) { wxDialogBase::SetWindowStyleFlag(style); - if( HasFlag(wxRESIZE_BORDER) ) + if ( HasFlag(wxRESIZE_BORDER) ) CreateGripper(); else DestroyGripper(); @@ -357,13 +304,15 @@ void wxDialog::SetWindowStyleFlag(long style) void wxDialog::CreateGripper() { - if( !m_hGripper ) + if ( !m_hGripper ) { + // just create it here, it will be positioned and shown later m_hGripper = (WXHWND)::CreateWindow ( wxT("SCROLLBAR"), wxT(""), - WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | + WS_CHILD | + WS_CLIPSIBLINGS | SBS_SIZEGRIP | SBS_SIZEBOX | SBS_SIZEBOXBOTTOMRIGHTALIGN, @@ -373,9 +322,6 @@ void wxDialog::CreateGripper() wxGetInstance(), NULL ); - - // position the gripper correctly after creation - ResizeGripper(); } } @@ -383,6 +329,14 @@ void wxDialog::DestroyGripper() { if ( m_hGripper ) { + // we used to have trouble with gripper appearing on top (and hence + // overdrawing) the other, real, dialog children -- check that this + // isn't the case automatically (but notice that this could be false if + // we're not shown at all as in this case ResizeGripper() might not + // have been called yet) + wxASSERT_MSG( !IsShown() || + ::GetWindow((HWND)m_hGripper, GW_HWNDNEXT) == 0, + wxT("Bug in wxWidgets: gripper should be at the bottom of Z-order") ); ::DestroyWindow((HWND) m_hGripper); m_hGripper = 0; } @@ -390,14 +344,17 @@ void wxDialog::DestroyGripper() void wxDialog::ShowGripper(bool show) { - wxASSERT_MSG( m_hGripper, _T("shouldn't be called if we have no gripper") ); + wxASSERT_MSG( m_hGripper, wxT("shouldn't be called if we have no gripper") ); + + if ( show ) + ResizeGripper(); ::ShowWindow((HWND)m_hGripper, show ? SW_SHOW : SW_HIDE); } void wxDialog::ResizeGripper() { - wxASSERT_MSG( m_hGripper, _T("shouldn't be called if we have no gripper") ); + wxASSERT_MSG( m_hGripper, wxT("shouldn't be called if we have no gripper") ); HWND hwndGripper = (HWND)m_hGripper; @@ -410,6 +367,21 @@ void wxDialog::ResizeGripper() SWP_NOACTIVATE); } +void wxDialog::OnWindowCreate(wxWindowCreateEvent& event) +{ + if ( m_hGripper && IsShown() && + event.GetWindow() && event.GetWindow()->GetParent() == this ) + { + // Put gripper below the newly created child window + ::SetWindowPos((HWND)m_hGripper, HWND_BOTTOM, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); + } + + event.Skip(); +} + +#endif // wxUSE_DIALOG_SIZEGRIP + // ---------------------------------------------------------------------------- // wxWin event handlers // ---------------------------------------------------------------------------- @@ -491,6 +463,7 @@ WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPar break; case WM_SIZE: +#if wxUSE_DIALOG_SIZEGRIP if ( m_hGripper ) { switch ( wParam ) @@ -501,12 +474,9 @@ WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPar case SIZE_RESTORED: ShowGripper(true); - // fall through - - default: - ResizeGripper(); } } +#endif // wxUSE_DIALOG_SIZEGRIP // the Windows dialogs unfortunately are not meant to be resizeable // at all and their standard class doesn't include CS_[VH]REDRAW