+ wxSize best(wBox, hBox);
+ CacheBestSize(best);
+ return best;
+}
+
+void wxStaticBox::GetBordersForSizer(int *borderTop, int *borderOther) const
+{
+ wxStaticBoxBase::GetBordersForSizer(borderTop, borderOther);
+
+ // need extra space, don't know how much but this seems to be enough
+ *borderTop += GetCharHeight()/3;
+}
+
+// all the hacks below are not necessary for WinCE
+#ifndef __WXWINCE__
+
+WXLRESULT wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+ if ( nMsg == WM_NCHITTEST )
+ {
+ // This code breaks some other processing such as enter/leave tracking
+ // so it's off by default.
+
+ static int s_useHTClient = -1;
+ if (s_useHTClient == -1)
+ s_useHTClient = wxSystemOptions::GetOptionInt(wxT("msw.staticbox.htclient"));
+ if (s_useHTClient == 1)
+ {
+ int xPos = GET_X_LPARAM(lParam);
+ int yPos = GET_Y_LPARAM(lParam);
+
+ ScreenToClient(&xPos, &yPos);
+
+ // Make sure you can drag by the top of the groupbox, but let
+ // other (enclosed) controls get mouse events also
+ if ( yPos < 10 )
+ return (long)HTCLIENT;
+ }
+ }
+
+ if ( nMsg == WM_PRINTCLIENT )
+ {
+ // we have to process WM_PRINTCLIENT ourselves as otherwise child
+ // windows' background (eg buttons in radio box) would never be drawn
+ // unless we have a parent with non default background
+
+ // so check first if we have one
+ if ( !HandlePrintClient((WXHDC)wParam) )
+ {
+ // no, we don't, erase the background ourselves
+ // (don't use our own) - see PaintBackground for explanation
+ wxBrush brush(GetParent()->GetBackgroundColour());
+ wxFillRect(GetHwnd(), (HDC)wParam, GetHbrushOf(brush));
+ }
+
+ return 0;
+ }
+
+ if ( nMsg == WM_UPDATEUISTATE )
+ {
+ // DefWindowProc() redraws just the static box text when it gets this
+ // message and it does it using the standard (blue in standard theme)
+ // colour and not our own label colour that we use in PaintForeground()
+ // resulting in the label mysteriously changing the colour when e.g.
+ // "Alt" is pressed anywhere in the window, see #12497.
+ //
+ // To avoid this we simply refresh the window forcing our own code
+ // redrawing the label in the correct colour to be called. This is
+ // inefficient but there doesn't seem to be anything else we can do.
+ //
+ // Notice that the problem is XP-specific and doesn't arise under later
+ // systems.
+ if ( m_hasFgCol && wxGetWinVersion() == wxWinVersion_XP )
+ Refresh();
+ }
+
+ return wxControl::MSWWindowProc(nMsg, wParam, lParam);
+}
+
+// ----------------------------------------------------------------------------
+// static box drawing
+// ----------------------------------------------------------------------------
+
+/*
+ We draw the static box ourselves because it's the only way to prevent it
+ from flickering horribly on resize (because everything inside the box is
+ erased twice: once when the box itself is repainted and second time when
+ the control inside it is repainted) without using WS_EX_TRANSPARENT style as
+ we used to do and which resulted in other problems.
+ */
+
+// MSWGetRegionWithoutSelf helper: removes the given rectangle from region
+static inline void
+SubtractRectFromRgn(HRGN hrgn, int left, int top, int right, int bottom)
+{
+ AutoHRGN hrgnRect(::CreateRectRgn(left, top, right, bottom));
+ if ( !hrgnRect )
+ {
+ wxLogLastError(wxT("CreateRectRgn()"));
+ return;
+ }
+
+ ::CombineRgn(hrgn, hrgn, hrgnRect, RGN_DIFF);
+}
+
+void wxStaticBox::MSWGetRegionWithoutSelf(WXHRGN hRgn, int w, int h)
+{
+ HRGN hrgn = (HRGN)hRgn;
+
+ // remove the area occupied by the static box borders from the region
+ int borderTop, border;
+ GetBordersForSizer(&borderTop, &border);
+
+ // top
+ SubtractRectFromRgn(hrgn, 0, 0, w, borderTop);
+
+ // bottom
+ SubtractRectFromRgn(hrgn, 0, h - border, w, h);
+
+ // left
+ SubtractRectFromRgn(hrgn, 0, 0, border, h);
+
+ // right
+ SubtractRectFromRgn(hrgn, w - border, 0, w, h);