X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/34ea3c74912db9d9142c1af0342f911f748e128d..85fb220621d0b87a5570d114d753826a69eb8f41:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index a2c31ccb8f..21055bce76 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -436,9 +436,6 @@ void wxWindowMSW::Init() m_childrenDisabled = NULL; m_frozenness = 0; - // wxWnd - m_hMenu = 0; - m_hWnd = 0; m_xThumbSize = 0; @@ -1145,11 +1142,16 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const // wxTopLevelWindow) should remove WS_CHILD in their MSWGetStyle() WXDWORD style = WS_CHILD; - if ( flags & wxCLIP_CHILDREN ) - style |= WS_CLIPCHILDREN; + // using this flag results in very significant reduction in flicker, + // especially with controls inside the static boxes (as the interior of the + // box is not redrawn twice) + style |= WS_CLIPCHILDREN; + + // it doesn't seem useful to use WS_CLIPSIBLINGS here as we officially + // don't support overlapping windows and it only makes sense for them and, + // presumably, gives the system some extra work (to manage more clipping + // regions), so avoid it alltogether - if ( flags & wxCLIP_SIBLINGS ) - style |= WS_CLIPSIBLINGS; if ( flags & wxVSCROLL ) style |= WS_VSCROLL; @@ -1254,15 +1256,17 @@ 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; - if ( GetKeyState( VK_LBUTTON ) ) + + // Only the high-order bit should be tested + if ( GetKeyState( VK_LBUTTON ) & (1<<15) ) state |= MK_LBUTTON; - if ( GetKeyState( VK_MBUTTON ) ) + if ( GetKeyState( VK_MBUTTON ) & (1<<15) ) state |= MK_MBUTTON; - if ( GetKeyState( VK_RBUTTON ) ) + if ( GetKeyState( VK_RBUTTON ) & (1<<15) ) state |= MK_RBUTTON; POINT pt; @@ -1526,7 +1530,8 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height) width = 0; if (height < 0) height = 0; - if ( !::MoveWindow(GetHwnd(), x, y, width, height, IsShown() /*Repaint?*/) ) + + if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) ) { wxLogLastError(wxT("MoveWindow")); } @@ -2222,11 +2227,16 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l (void)HandleDestroy(); break; + case WM_SIZE: + processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam); + break; + case WM_MOVE: processed = HandleMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; #if !defined(__WXWINCE__) + // TODO: move those in WM_WINDOWPOSCHANGING case above case WM_MOVING: { LPRECT pRect = (LPRECT)lParam; @@ -2244,13 +2254,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l } } break; -#endif - case WM_SIZE: - processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam); - break; - -#if !defined(__WXWINCE__) case WM_SIZING: { LPRECT pRect = (LPRECT)lParam; @@ -2268,7 +2272,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l } } break; -#endif +#endif // !__WXWINCE__ #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) case WM_ACTIVATEAPP: @@ -3938,9 +3942,6 @@ extern wxCOLORMAP *wxGetStdColourMap() bool wxWindowMSW::HandlePaint() { -// if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND) -// return false; - HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle if ( !hRegion ) wxLogLastError(wxT("CreateRectRgn")); @@ -3980,10 +3981,6 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event) bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc) { - // Prevents flicker when dragging - if ( ::IsIconic(GetHwnd()) ) - return true; - wxDCTemp dc(hdc); dc.SetHDC(hdc); @@ -4004,53 +4001,83 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc) void wxWindowMSW::OnEraseBackground(wxEraseEvent& event) { - switch ( GetBackgroundStyle() ) + // standard controls always erase their background themselves (although the + // user may try to override it in a derived class) + if ( IsOfStandardClass() ) { - default: - wxFAIL_MSG( _T("unexpected background style") ); - // fall through + event.Skip(); + return; + } - case wxBG_STYLE_CUSTOM: - // don't skip the event here, custom background means that the app - // is drawing it itself in its OnPaint() - break; + if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM ) + { + // don't skip the event here, custom background means that the app + // is drawing it itself in its OnPaint(), so don't draw it at all + // now to avoid flicker + return; + } - case wxBG_STYLE_SYSTEM: -#if wxUSE_NOTEBOOK && wxUSE_UXTHEME && !defined(__WXUNIVERSAL__) - // automatically apply the tab control theme background to any - // child panels to have the same look as the native property sheet - // dialogs - if ( !IsOfStandardClass() ) - { - for ( wxWindow *win = this; win; win = win->GetParent() ) - { - wxNotebook *nbook = wxDynamicCast(win, wxNotebook); - if ( nbook ) - { - nbook->DoEraseBackground(event); - return; - } - } - } -#endif // wxUSE_NOTEBOOK - event.Skip(); - break; - case wxBG_STYLE_COLOUR: - // we have a fixed solid background colour, do use it - RECT rect; - ::GetClientRect(GetHwnd(), &rect); + // 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 + { + // let the system paint the background + event.Skip(); + } +} - HBRUSH hBrush = ::CreateSolidBrush( - wxColourToPalRGB(GetBackgroundColour())); - if ( !hBrush ) - wxLogLastError(wxT("CreateSolidBrush")); +WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child) +{ + wxColour col = MSWGetBgColourForChild(child); + if ( col.Ok() ) + { + // draw children with the same colour as the parent + wxBrush *brush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID); - HDC hdc = GetHdcOf((*event.GetDC())); + return (WXHBRUSH)brush->GetResourceHandle(); + } - ::FillRect(hdc, &rect, hBrush); - ::DeleteObject(hBrush); + return 0; +} + +wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow *child) +{ + return m_inheritBgCol || (m_hasBgCol && child == this) + ? GetBackgroundColour() + : wxNullColour; +} + +WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC) +{ + return parent->MSWGetBgBrushForChild(hDC, (wxWindow *)this); +} + +WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC) +{ + for ( wxWindow *win = (wxWindow *)this; win; win = win->GetParent() ) + { + WXHBRUSH hBrush = MSWGetBgBrushForSelf(win, hDC); + if ( hBrush ) + return hBrush; + + // background is not inherited beyond the windows which have their own + // 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; } + + return 0; } // --------------------------------------------------------------------------- @@ -4954,8 +4981,10 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam) case VK_NUMLOCK: id = WXK_NUMLOCK; break; case VK_SCROLL: id = WXK_SCROLL; break; + // the mapping for these keys may be incorrect on non-US keyboards so + // maybe we shouldn't map them to ASCII values at all case VK_OEM_1: id = ';'; break; - case VK_OEM_PLUS: id = '='; break; + case VK_OEM_PLUS: id = '+'; break; case VK_OEM_COMMA: id = ','; break; case VK_OEM_MINUS: id = '-'; break; case VK_OEM_PERIOD: id = '.'; break; @@ -5070,7 +5099,7 @@ bool wxGetKeyState(wxKeyCode key) bool bVirtual; //High order with GetAsyncKeyState only available on WIN32 -#ifdef __WIN32__ +#ifdef __WIN32__ //If the requested key is a LED key, return //true if the led is pressed if (key == WXK_NUMLOCK || @@ -5078,12 +5107,12 @@ bool wxGetKeyState(wxKeyCode key) key == WXK_SCROLL) { #endif - //low order bit means LED is highlighted, + //low order bit means LED is highlighted, //high order means key is down //Here, for compat with other ports we want both return GetKeyState( wxCharCodeWXToMSW(key, &bVirtual) ) != 0; -#ifdef __WIN32__ +#ifdef __WIN32__ } else {