m_frozenness = 0;
m_hWnd = 0;
+ m_hDWP = 0;
m_xThumbSize = 0;
m_yThumbSize = 0;
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"));
+ }
}
}
(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 )
+ {
+ HDWP hDWP = (HDWP)m_hDWP;
+ m_hDWP = NULL;
+
+ // put all child controls in place at once now
+ if ( !::EndDeferWindowPos(hDWP) )
+ {
+ wxLogLastError(_T("EndDeferWindowPos"));
+ }
+ }
+ break;
+#endif // __SMARTPHONE__
+
case WM_SIZE:
processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
break;
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;
// 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);
wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow *child)
{
- return m_inheritBgCol || (m_hasBgCol && child == this)
- ? 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)