X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/57be9aac75e181c199335802a60811c94665d042..13973396cb244918489fbc14f6112549c4687881:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index b5f9bec74a..e797f3fd61 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -437,6 +437,7 @@ void wxWindowMSW::Init() m_frozenness = 0; m_hWnd = 0; + m_hDWP = 0; m_xThumbSize = 0; m_yThumbSize = 0; @@ -1256,7 +1257,7 @@ void wxWindowMSW::OnInternalIdle() // changed by the time the OnInternalIdle function is called, so 'state' // may be meaningless. int state = 0; - if ( wxIsShiftDown() ) + if ( wxIsShiftDown() ) state |= MK_SHIFT; if ( wxIsCtrlDown() ) state |= MK_CONTROL; @@ -1531,9 +1532,30 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height) if (height < 0) height = 0; - if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) ) + // if our parent had prepared a defer window handle for us, use it + wxWindowMSW *parent = GetParent(); + HDWP hdwp = parent ? (HDWP)parent->m_hDWP : NULL; + if ( hdwp ) { - wxLogLastError(wxT("MoveWindow")); + hdwp = ::DeferWindowPos(hdwp, GetHwnd(), NULL, + x, y, width, height, + SWP_NOZORDER); + if ( !hdwp ) + { + wxLogLastError(_T("DeferWindowPos")); + } + + // hdwp must be updated as it may have been changed + parent->m_hDWP = (WXHANDLE)hdwp; + } + + // otherwise (or if deferring failed) move the window in place immediately + if ( !hdwp ) + { + if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) ) + { + wxLogLastError(wxT("MoveWindow")); + } } } @@ -1876,8 +1898,21 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) case VK_ESCAPE: { #if wxUSE_BUTTON - wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL), - wxButton); + wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL),wxButton); + + // our own wxLogDialog should react to Esc + // without Cancel button but this is a private class + // so let's try recognize it by content + #if wxUSE_LOG_DIALOG + if ( !btn && + wxDynamicCast(this,wxDialog) && + FindWindow(wxID_MORE) && + FindWindow(wxID_OK) && + !FindWindow(wxID_CANCEL) && + GetTitle().MakeLower().StartsWith(wxTheApp->GetAppName().c_str()) + ) + btn = wxDynamicCast(FindWindow(wxID_OK),wxButton); + #endif // wxUSE_LOG_DIALOG if ( btn && btn->IsEnabled() ) { // if we do have a cancel button, do press it @@ -1918,7 +1953,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) bProcess = false; } // FIXME: this should be handled by - // wxNavigationKeyEvent handler and not here!! + // wxNavigationKeyEvent handler and not here! else { #if wxUSE_BUTTON @@ -2227,6 +2262,46 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l (void)HandleDestroy(); break; +#ifndef __SMARTPHONE__ // or wxWinCE in general ? + case WM_WINDOWPOSCHANGING: + { + WINDOWPOS *wp = wx_reinterpret_cast(WINDOWPOS *, lParam); + + if ( wp->flags & SWP_NOSIZE ) + break; + + // when we resize this window, its children are probably going + // to be repositioned as well, prepare to use DeferWindowPos() + // for them + const int numChildren = GetChildren().GetCount(); + if ( numChildren > 1 ) + { + m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren); + if ( !m_hDWP ) + { + wxLogLastError(_T("BeginDeferWindowPos")); + } + } + } + break; + + case WM_WINDOWPOSCHANGED: + // first let DefWindowProc() handle the message: it will generate + // WM_MOVE and WM_SIZE as needed + processed = MSWDefWindowProc(message, wParam, lParam) == 0; + + // then change the positions of all child windows at once + if ( m_hDWP ) + { + // put all child controls in place at once now + if ( !::EndDeferWindowPos((HDWP)m_hDWP) ) + { + wxLogLastError(_T("EndDeferWindowPos")); + } + } + break; +#endif // __SMARTPHONE__ + case WM_SIZE: processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam); break; @@ -4001,9 +4076,10 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc) void wxWindowMSW::OnEraseBackground(wxEraseEvent& event) { - // standard controls always erase their background themselves (although the - // user may try to override it in a derived class) - if ( IsOfStandardClass() ) + // standard non top level controls (i.e. except the dialogs) always erase + // their background themselves in HandleCtlColor() or have some control- + // specific ways to set the colours (common controls) + if ( IsOfStandardClass() && !IsTopLevel() ) { event.Skip(); return; @@ -4019,21 +4095,26 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event) // do default background painting - wxDC& dc = *event.GetDC(); - HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC()); - if ( hBrush ) - { - RECT rc; - ::GetClientRect(GetHwnd(), &rc); - ::FillRect(GetHdcOf(dc), &rc, hBrush); - } - else + if ( !DoEraseBackground(*event.GetDC()) ) { // let the system paint the background event.Skip(); } } +bool wxWindowMSW::DoEraseBackground(wxDC& dc) +{ + HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC()); + if ( !hBrush ) + return false; + + RECT rc; + ::GetClientRect(GetHwnd(), &rc); + ::FillRect(GetHdcOf(dc), &rc, hBrush); + + return true; +} + WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child) { wxColour col = MSWGetBgColourForChild(child); @@ -4048,9 +4129,26 @@ WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child) return 0; } -wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow * WXUNUSED(child)) +wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow *child) { - return m_inheritBgCol ? GetBackgroundColour() : wxNullColour; + if ( m_hasBgCol ) + { + // our background colour applies to: + // 1. this window itself, always + // 2. all children unless the colour is "not inheritable" + // 3. immediate transparent children which should show the same + // background as we do, but not for transparent grandchildren + // which use the background of their immediate parent instead + if ( m_inheritBgCol || + child == this || + (child->HasTransparentBackground() && + child->GetParent() == this) ) + { + return GetBackgroundColour(); + } + } + + return wxNullColour; } WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC) @@ -4067,8 +4165,11 @@ WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC) return hBrush; // background is not inherited beyond the windows which have their own - // fixed background such as top level windows and notebooks - if ( win->ProvidesBackground() ) + // fixed background such as top level windows and notebooks and for + // windows for which a custom colour had been explicitly set with + // SetOwnBackgroundColour() and so shouldn't affect its children + if ( win->ProvidesBackground() || + (win->m_hasBgCol && !win->m_inheritBgCol) ) break; }