]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
reverted use of DeferWindowPos() instead of MoveWindow()
[wxWidgets.git] / src / msw / window.cpp
index 864a390d85bc20e351397752c1431633b3201306..b5f9bec74a90463caed3c11671799329139fbaf4 100644 (file)
@@ -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,78 @@ 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();
+    }
+
+    return 0;
+}
 
-            ::FillRect(hdc, &rect, hBrush);
-            ::DeleteObject(hBrush);
+wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow * WXUNUSED(child))
+{
+    return m_inheritBgCol ? 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
+        if ( win->ProvidesBackground() )
+            break;
     }
+
+    return 0;
 }
 
 // ---------------------------------------------------------------------------
@@ -4954,6 +4976,8 @@ 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_COMMA:  id = ','; break;
@@ -5070,7 +5094,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 +5102,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
     {
@@ -5815,7 +5839,11 @@ public:
     static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
     {
         MSG *msg = (MSG*)lParam;
-        if ( msg->message == WM_NULL )
+
+        // only process the message if it is actually going to be removed from
+        // the message queue, this prevents that the same event from being
+        // processed multiple times if now someone just called PeekMessage()
+        if ( msg->message == WM_NULL && wParam == PM_REMOVE )
         {
             wxTheApp->ProcessPendingEvents();
         }