]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/statbox.cpp
Applied patch #15540: wxRichTextTable: crashes due to an invalid focus object (dghart)
[wxWidgets.git] / src / msw / statbox.cpp
index 75306978e01fd8d987e3245d23ded74ed416cda0..678a2594cff0245ac8310816db7a81ab8f8dc4f8 100644 (file)
@@ -4,7 +4,6 @@
 // Author:      Julian Smart
 // Modified by:
 // Created:     04/01/98
-// RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
@@ -33,6 +32,7 @@
     #include "wx/dcclient.h"
     #include "wx/dcmemory.h"
     #include "wx/image.h"
+    #include "wx/sizer.h"
 #endif
 
 #include "wx/notebook.h"
@@ -81,7 +81,13 @@ bool wxStaticBox::Create(wxWindow *parent,
 
 #ifndef __WXWINCE__
     if (!wxSystemOptions::IsFalse(wxT("msw.staticbox.optimized-paint")))
+    {
         Connect(wxEVT_PAINT, wxPaintEventHandler(wxStaticBox::OnPaint));
+
+        // Our OnPaint() completely erases our background, so don't do it in
+        // WM_ERASEBKGND too to avoid flicker.
+        SetBackgroundStyle(wxBG_STYLE_PAINT);
+    }
 #endif // !__WXWINCE__
 
     return true;
@@ -98,11 +104,15 @@ WXDWORD wxStaticBox::MSWGetStyle(long style, WXDWORD *exstyle) const
     if ( exstyle )
     {
 #ifndef __WXWINCE__
+        // We may have children inside this static box, so use this style for
+        // TAB navigation to work if we ever use IsDialogMessage() to implement
+        // it (currently we don't because it's too buggy and implement TAB
+        // navigation ourselves, but this could change in the future).
+        *exstyle |= WS_EX_CONTROLPARENT;
+
         if (wxSystemOptions::IsFalse(wxT("msw.staticbox.optimized-paint")))
-            *exstyle = WS_EX_TRANSPARENT;
-        else
+            *exstyle |= WS_EX_TRANSPARENT;
 #endif
-            *exstyle = 0;
     }
 
     styleWin |= BS_GROUPBOX;
@@ -118,6 +128,9 @@ WXDWORD wxStaticBox::MSWGetStyle(long style, WXDWORD *exstyle) const
 
 wxSize wxStaticBox::DoGetBestSize() const
 {
+    wxSize best;
+
+    // Calculate the size needed by the label
     int cx, cy;
     wxGetCharSize(GetHWND(), &cx, &cy, GetFont());
 
@@ -127,8 +140,19 @@ wxSize wxStaticBox::DoGetBestSize() const
     wBox += 3*cx;
     int hBox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
 
-    wxSize best(wBox, hBox);
-    CacheBestSize(best);
+    // If there is a sizer then the base best size is the sizer's minimum
+    if (GetSizer() != NULL)
+    {
+        wxSize cm(GetSizer()->CalcMin());
+        best = ClientToWindowSize(cm);
+        // adjust for a long label if needed
+        best.x = wxMax(best.x, wBox);
+    }
+    // otherwise the best size falls back to the label size
+    else
+    {
+        best = wxSize(wBox, hBox);
+    }
     return best;
 }
 
@@ -260,8 +284,14 @@ WXHRGN wxStaticBox::MSWGetRegionWithoutChildren()
     HRGN hrgn = ::CreateRectRgn(rc.left, rc.top, rc.right + 1, rc.bottom + 1);
     bool foundThis = false;
 
-    // iterate over all child windows (not just wxWindows but all windows)
-    for ( HWND child = ::GetWindow(GetHwndOf(GetParent()), GW_CHILD);
+    // Iterate over all sibling windows as in the old wxWidgets API the
+    // controls appearing inside the static box were created as its siblings
+    // and not children. This is now deprecated but should still work.
+    //
+    // Also notice that we must iterate over all windows, not just all
+    // wxWindows, as there may be composite windows etc.
+    HWND child;
+    for ( child = ::GetWindow(GetHwndOf(GetParent()), GW_CHILD);
           child;
           child = ::GetWindow(child, GW_HWNDNEXT) )
     {
@@ -313,6 +343,23 @@ WXHRGN wxStaticBox::MSWGetRegionWithoutChildren()
         }
     }
 
+    // Also iterate over all children of the static box, we need to clip them
+    // out as well.
+    for ( child = ::GetWindow(GetHwnd(), GW_CHILD);
+          child;
+          child = ::GetWindow(child, GW_HWNDNEXT) )
+    {
+        if ( !::IsWindowVisible(child) )
+        {
+            // if the window isn't visible then it doesn't need clipped
+            continue;
+        }
+
+        ::GetWindowRect(child, &rc);
+        AutoHRGN hrgnChild(::CreateRectRgnIndirect(&rc));
+        ::CombineRgn(hrgn, hrgn, hrgnChild, RGN_DIFF);
+    }
+
     return (WXHRGN)hrgn;
 }
 
@@ -349,6 +396,7 @@ void wxStaticBox::PaintForeground(wxDC& dc, const RECT& rc)
     wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
     MSWDefWindowProc(WM_PAINT, (WPARAM)GetHdcOf(*impl), 0);
 
+#if wxUSE_UXTHEME
     // when using XP themes, neither setting the text colour nor transparent
     // background mode doesn't change anything: the static box def window proc
     // still draws the label in its own colours, so we need to redraw the text
@@ -460,16 +508,17 @@ void wxStaticBox::PaintForeground(wxDC& dc, const RECT& rc)
         if ( !rtl )
         {
             RECT rc2 = { x, 0, x + width, y };
-            ::DrawText(hdc, label.wx_str(), label.length(), &rc2,
+            ::DrawText(hdc, label.t_str(), label.length(), &rc2,
                        drawTextFlags);
         }
         else // RTL
         {
             RECT rc2 = { x, 0, x - width, y };
-            ::DrawText(hdc, label.wx_str(), label.length(), &rc2,
+            ::DrawText(hdc, label.t_str(), label.length(), &rc2,
                        drawTextFlags | DT_RTLREADING);
         }
     }
+#endif // wxUSE_UXTHEME
 }
 
 void wxStaticBox::OnPaint(wxPaintEvent& WXUNUSED(event))