]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
respect label foreground colour for static boxes when using XP themes
[wxWidgets.git] / src / msw / window.cpp
index 9048400d3005d8e816304e0ce24459c01aa85f7d..950b149b590be30ab5025118b82f39a8500edf88 100644 (file)
@@ -231,6 +231,28 @@ bool GetCursorPosWinCE(POINT* pt)
 }
 #endif
 
 }
 #endif
 
+// ---------------------------------------------------------------------------
+// wxWindowExtraData
+// ---------------------------------------------------------------------------
+
+#if USE_DEFER_BUG_WORKAROUND
+// This class is used to hold additional data memebers that were added after
+// the stable 2.6.0 release.  They should be moved into wxWindow for 2.7 after
+// binary compatibility is no longer being maintained.
+
+class wxWindowExtraData {
+public:
+    wxWindowExtraData()
+        : m_pendingPosition(wxDefaultPosition),
+          m_pendingSize(wxDefaultSize)
+    {}
+
+    wxPoint     m_pendingPosition;
+    wxSize      m_pendingSize;
+};
+
+#endif
+
 // ---------------------------------------------------------------------------
 // event tables
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // event tables
 // ---------------------------------------------------------------------------
@@ -465,6 +487,10 @@ void wxWindowMSW::Init()
     m_lastMouseY = -1;
     m_lastMouseEvent = -1;
 #endif // wxUSE_MOUSEEVENT_HACK
     m_lastMouseY = -1;
     m_lastMouseEvent = -1;
 #endif // wxUSE_MOUSEEVENT_HACK
+
+#if USE_DEFER_BUG_WORKAROUND
+    m_extraData = new wxWindowExtraData;
+#endif
 }
 
 // Destructor
 }
 
 // Destructor
@@ -512,6 +538,10 @@ wxWindowMSW::~wxWindowMSW()
     }
 
     delete m_childrenDisabled;
     }
 
     delete m_childrenDisabled;
+
+#if USE_DEFER_BUG_WORKAROUND
+    delete m_extraData;
+#endif
 }
 
 // real construction (Init() must have been called before!)
 }
 
 // real construction (Init() must have been called before!)
@@ -1366,7 +1396,8 @@ void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect)
             pRect = NULL;
         }
 
             pRect = NULL;
         }
 
-#ifndef __SMARTPHONE__
+       // RedrawWindow not available on SmartPhone or eVC++ 3
+#if !defined(__SMARTPHONE__) && !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
         UINT flags = RDW_INVALIDATE | RDW_ALLCHILDREN;
         if ( eraseBack )
             flags |= RDW_ERASE;
         UINT flags = RDW_INVALIDATE | RDW_ALLCHILDREN;
         if ( eraseBack )
             flags |= RDW_ERASE;
@@ -1555,7 +1586,7 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
     HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL;
 #else
     HDWP hdwp = 0;
     HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL;
 #else
     HDWP hdwp = 0;
-#endif    
+#endif
 
     wxMoveWindowDeferred(hdwp, this, GetHwnd(), x, y, width, height);
 
 
     wxMoveWindowDeferred(hdwp, this, GetHwnd(), x, y, width, height);
 
@@ -1578,9 +1609,28 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 {
     // get the current size and position...
     int currentX, currentY;
 {
     // get the current size and position...
     int currentX, currentY;
+    int currentW, currentH;
+
+#if USE_DEFER_BUG_WORKAROUND
+    currentX = m_extraData->m_pendingPosition.x;
+    if (currentX == wxDefaultCoord)
+        GetPosition(&currentX, NULL);
+
+    currentY = m_extraData->m_pendingPosition.y;
+    if (currentY == wxDefaultCoord)
+        GetPosition(NULL, &currentY);
+
+    currentW = m_extraData->m_pendingSize.x;
+    if (currentW == wxDefaultCoord)
+        GetSize(&currentW, NULL);
+
+    currentH = m_extraData->m_pendingSize.y;
+    if (currentH == wxDefaultCoord)
+        GetSize(NULL, &currentH);
+#else
     GetPosition(&currentX, &currentY);
     GetPosition(&currentX, &currentY);
-    int currentW,currentH;
     GetSize(&currentW, &currentH);
     GetSize(&currentW, &currentH);
+#endif
 
     // ... and don't do anything (avoiding flicker) if it's already ok
     if ( x == currentX && y == currentY &&
 
     // ... and don't do anything (avoiding flicker) if it's already ok
     if ( x == currentX && y == currentY &&
@@ -1630,6 +1680,24 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
         }
     }
 
         }
     }
 
+#if USE_DEFER_BUG_WORKAROUND
+    // We don't actually use the hdwp here, but we need to know whether to
+    // save the pending dimensions or not.  This isn't done in DoMoveWindow
+    // (where the hdwp is used) because some controls have thier own
+    // DoMoveWindow so it is easier to catch it here.
+    HDWP hdwp = GetParent() && !IsTopLevel() ? (HDWP)GetParent()->m_hDWP : NULL;
+    if (hdwp)
+    {
+        m_extraData->m_pendingPosition = wxPoint(x, y);
+        m_extraData->m_pendingSize = wxSize(width, height);
+    }
+    else
+    {
+        m_extraData->m_pendingPosition = wxDefaultPosition;
+        m_extraData->m_pendingSize = wxDefaultSize;
+    }
+#endif
+
     DoMoveWindow(x, y, width, height);
 }
 
     DoMoveWindow(x, y, width, height);
 }
 
@@ -1729,7 +1797,7 @@ void wxWindowMSW::GetTextExtent(const wxString& string,
 
     SIZE sizeRect;
     TEXTMETRIC tm;
 
     SIZE sizeRect;
     TEXTMETRIC tm;
-    GetTextExtentPoint(hdc, string, string.length(), &sizeRect);
+    ::GetTextExtentPoint32(hdc, string, string.length(), &sizeRect);
     GetTextMetrics(hdc, &tm);
 
     if ( x )
     GetTextMetrics(hdc, &tm);
 
     if ( x )
@@ -2310,6 +2378,31 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             break;
 #endif // !__WXWINCE__
 
             break;
 #endif // !__WXWINCE__
 
+        case WM_WINDOWPOSCHANGED:
+            {
+                WINDOWPOS *lpPos = (WINDOWPOS *)lParam;
+
+                if ( !(lpPos->flags & SWP_NOSIZE) )
+                {
+                    RECT rc;
+                    ::GetClientRect(GetHwnd(), &rc);
+
+                    AutoHRGN hrgnClient(::CreateRectRgnIndirect(&rc));
+                    AutoHRGN hrgnNew(::CreateRectRgn(lpPos->x,  lpPos->y,
+                                                     lpPos->cx, lpPos->cy));
+                    AutoHRGN hrgn(::CreateRectRgn(0, 0, 0, 0));
+
+                    // we need to invalidate any new exposed areas here
+                    // to force them to repaint
+                    if ( ::CombineRgn(hrgn, hrgnNew, hrgnClient, RGN_DIFF) != NULLREGION )
+                        ::InvalidateRgn(GetHwnd(), hrgn, TRUE);
+                    if ( ::CombineRgn(hrgn, hrgnClient, hrgnNew, RGN_DIFF) != NULLREGION )
+                        ::InvalidateRgn(GetHwnd(), hrgn, TRUE);
+
+                }
+            }
+            break;
+
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
             // This implicitly sends a wxEVT_ACTIVATE_APP event
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
             // This implicitly sends a wxEVT_ACTIVATE_APP event
@@ -3511,7 +3604,7 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
     if ( !::GetCursorPosWinCE(&pt))
 #else
     if ( !::GetCursorPos(&pt) )
     if ( !::GetCursorPosWinCE(&pt))
 #else
     if ( !::GetCursorPos(&pt) )
-#endif        
+#endif
     {
         wxLogLastError(wxT("GetCursorPos"));
     }
     {
         wxLogLastError(wxT("GetCursorPos"));
     }
@@ -4077,6 +4170,10 @@ bool wxWindowMSW::HandlePrintClient(WXHDC hDC)
     //
     // also note that in this case lParam == PRF_CLIENT but we're
     // clearly expected to paint the background and nothing else!
     //
     // also note that in this case lParam == PRF_CLIENT but we're
     // clearly expected to paint the background and nothing else!
+
+    if ( IsTopLevel() || InheritsBackgroundColour() )
+        return false;
+
     for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
     {
         if ( win->MSWPrintChild(hDC, (wxWindow *)this) )
     for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
     {
         if ( win->MSWPrintChild(hDC, (wxWindow *)this) )
@@ -4131,8 +4228,6 @@ bool wxWindowMSW::HandleMoving(wxRect& rect)
 
 bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
 {
 
 bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
 {
-    // when we resize this window, its children are probably going to be
-    // repositioned as well, prepare to use DeferWindowPos() for them
 #if USE_DEFERRED_SIZING
     // when we resize this window, its children are probably going to be
     // repositioned as well, prepare to use DeferWindowPos() for them
 #if USE_DEFERRED_SIZING
     // when we resize this window, its children are probably going to be
     // repositioned as well, prepare to use DeferWindowPos() for them
@@ -4144,13 +4239,13 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
         numChildren ++;
     }
 
         numChildren ++;
     }
 
-    // Protect against valid m_hDWP being overwritten    
+    // Protect against valid m_hDWP being overwritten
     bool useDefer = false;
 
     if ( numChildren > 1 )
     {
         if (!m_hDWP)
     bool useDefer = false;
 
     if ( numChildren > 1 )
     {
         if (!m_hDWP)
-        {        
+        {
             m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
             if ( !m_hDWP )
             {
             m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
             if ( !m_hDWP )
             {
@@ -4203,7 +4298,7 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
         // may have depending on what the users EVT_SIZE handler does...)
         HDWP hDWP = (HDWP)m_hDWP;
         m_hDWP = NULL;
         // may have depending on what the users EVT_SIZE handler does...)
         HDWP hDWP = (HDWP)m_hDWP;
         m_hDWP = NULL;
-        
+
         // do put all child controls in place at once
         if ( !::EndDeferWindowPos(hDWP) )
         {
         // do put all child controls in place at once
         if ( !::EndDeferWindowPos(hDWP) )
         {
@@ -4211,23 +4306,14 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
         }
 
 #if USE_DEFER_BUG_WORKAROUND
         }
 
 #if USE_DEFER_BUG_WORKAROUND
-        // Seems to be a bug in DeferWindowPos such that going from (a) to (b) to (a)
-        // doesn't work (omits last position/size). So check if there's a disparity,
-        // and correct.
+        // Reset our children's pending pos/size values.
         for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
               node;
               node = node->GetNext() )
         {
             wxWindow *child = node->GetData();
         for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
               node;
               node = node->GetNext() )
         {
             wxWindow *child = node->GetData();
-            wxSizer* sizer = child->GetContainingSizer();
-            if (sizer)
-            {
-                wxSizerItem* item = sizer->GetItem(child, true);
-                if (item->GetRect().GetPosition() != child->GetPosition())
-                {
-                    child->Move(item->GetRect().GetPosition());
-                }
-            }
+            child->m_extraData->m_pendingPosition = wxDefaultPosition;
+            child->m_extraData->m_pendingSize = wxDefaultSize;
         }
 #endif
     }
         }
 #endif
     }