Applied patch [ 1166587 ] [wxMSW] Removes all flicker from wxStaticBox
By Jamie Gadd git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33178 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -13,8 +13,8 @@ All:
|
|||||||
- Added wxTempFileOutputStream by Stas Sergeev.
|
- Added wxTempFileOutputStream by Stas Sergeev.
|
||||||
- Fixed wxDateTime::SetToWeekDayInSameWeek(Sun, Monday_First).
|
- Fixed wxDateTime::SetToWeekDayInSameWeek(Sun, Monday_First).
|
||||||
- Added WXK_SPECIAL keycodes for special hardware buttons.
|
- Added WXK_SPECIAL keycodes for special hardware buttons.
|
||||||
- Fixed bug with wxFile::Seek(-1, wxFromCurrent)
|
- Fixed bug with wxFile::Seek(-1, wxFromCurrent).
|
||||||
- Added wxString/C array constructors to wxArrayString
|
- Added wxString/C array constructors to wxArrayString.
|
||||||
|
|
||||||
All (GUI):
|
All (GUI):
|
||||||
|
|
||||||
@@ -26,29 +26,31 @@ All (GUI):
|
|||||||
- Restored ability to set a custom splitter sash size with SetSashSize.
|
- Restored ability to set a custom splitter sash size with SetSashSize.
|
||||||
- Fixed wxScrolledWindow sizer behaviour so that the virtual size
|
- Fixed wxScrolledWindow sizer behaviour so that the virtual size
|
||||||
isn't used to set the window size.
|
isn't used to set the window size.
|
||||||
- Added wxTE_BESTWRAP (based on patch by Mart Raudsepp)
|
- Added wxTE_BESTWRAP (based on patch by Mart Raudsepp).
|
||||||
- wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED is now only sent once at the end of
|
- wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED is now only sent once at the end of
|
||||||
splitter dragging and not after each CHANGING event (Jacobo Vilella Vilahur)
|
splitter dragging and not after each CHANGING event (Jacobo Vilella Vilahur).
|
||||||
|
|
||||||
Unix:
|
Unix:
|
||||||
|
|
||||||
- Fixed build on Linux/AMD64
|
- Fixed build on Linux/AMD64.
|
||||||
|
|
||||||
wxMSW:
|
wxMSW:
|
||||||
|
|
||||||
- Added "orient" parameter to wxMDIParentFrame::Tile()
|
- Added "orient" parameter to wxMDIParentFrame::Tile().
|
||||||
- wxTextCtrl with wxTE_RICH2 style now uses RichEdit 4.1 if available
|
- wxTextCtrl with wxTE_RICH2 style now uses RichEdit 4.1 if available.
|
||||||
- fix handling Alt-key events in wxComboBox (reported by Joakim Roubert)
|
- fix handling Alt-key events in wxComboBox (reported by Joakim Roubert).
|
||||||
- wxWindow::Refresh() refreshes the window children as well
|
- wxWindow::Refresh() refreshes the window children as well.
|
||||||
|
- Improved static box and radio box refresh and background colour
|
||||||
|
handling (Jamie Gadd).
|
||||||
|
|
||||||
wxGTK:
|
wxGTK:
|
||||||
|
|
||||||
- Improved wxSystemSettings::GetMetric() to work better with X11. (Mart Raudsepp)
|
- Improved wxSystemSettings::GetMetric() to work better with X11 (Mart Raudsepp).
|
||||||
- Corrected wxListBox selection handling.
|
- Corrected wxListBox selection handling.
|
||||||
- Corrected default button size handling for different themes.
|
- Corrected default button size handling for different themes.
|
||||||
- Corrected splitter sash size and look for different themes.
|
- Corrected splitter sash size and look for different themes.
|
||||||
- Fixed keyboard input for dead-keys.
|
- Fixed keyboard input for dead-keys.
|
||||||
- Added support for more wrapping styles (Mart Raudsepp)
|
- Added support for more wrapping styles (Mart Raudsepp).
|
||||||
|
|
||||||
wxMac:
|
wxMac:
|
||||||
|
|
||||||
|
@@ -144,6 +144,8 @@ protected:
|
|||||||
int sizeFlags = wxSIZE_AUTO);
|
int sizeFlags = wxSIZE_AUTO);
|
||||||
virtual wxSize DoGetBestSize() const;
|
virtual wxSize DoGetBestSize() const;
|
||||||
|
|
||||||
|
virtual WXHRGN MSWCalculateClippingRegion();
|
||||||
|
virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
|
||||||
|
|
||||||
// the buttons we contain
|
// the buttons we contain
|
||||||
wxSubwindows *m_radioButtons;
|
wxSubwindows *m_radioButtons;
|
||||||
|
@@ -48,8 +48,12 @@ protected:
|
|||||||
virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
|
virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
|
||||||
virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
|
virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
|
||||||
|
|
||||||
|
virtual WXHRGN MSWCalculateClippingRegion();
|
||||||
|
virtual void MSWClipBoxRegion(HRGN hrgn, const RECT *rc);
|
||||||
|
void OnPaint(wxPaintEvent& event);
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxStaticBox)
|
DECLARE_DYNAMIC_CLASS_NO_COPY(wxStaticBox)
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _WX_MSW_STATBOX_H_
|
#endif // _WX_MSW_STATBOX_H_
|
||||||
|
@@ -165,9 +165,6 @@ bool wxRadioBox::Create(wxWindow *parent,
|
|||||||
wxUnusedVar(val);
|
wxUnusedVar(val);
|
||||||
#endif // wxUSE_VALIDATORS/!wxUSE_VALIDATORS
|
#endif // wxUSE_VALIDATORS/!wxUSE_VALIDATORS
|
||||||
|
|
||||||
// and now create the buttons
|
|
||||||
HWND hwndParent = GetHwndOf(parent);
|
|
||||||
|
|
||||||
m_radioButtons = new wxSubwindows(n);
|
m_radioButtons = new wxSubwindows(n);
|
||||||
m_radioWidth = new int[n];
|
m_radioWidth = new int[n];
|
||||||
m_radioHeight = new int[n];
|
m_radioHeight = new int[n];
|
||||||
@@ -186,7 +183,7 @@ bool wxRadioBox::Create(wxWindow *parent,
|
|||||||
choices[i],
|
choices[i],
|
||||||
styleBtn,
|
styleBtn,
|
||||||
0, 0, 0, 0, // will be set in SetSize()
|
0, 0, 0, 0, // will be set in SetSize()
|
||||||
hwndParent,
|
GetHwnd(),
|
||||||
(HMENU)newId,
|
(HMENU)newId,
|
||||||
wxGetInstance(),
|
wxGetInstance(),
|
||||||
NULL);
|
NULL);
|
||||||
@@ -209,7 +206,7 @@ bool wxRadioBox::Create(wxWindow *parent,
|
|||||||
(void)::CreateWindow(_T("BUTTON"),
|
(void)::CreateWindow(_T("BUTTON"),
|
||||||
wxEmptyString,
|
wxEmptyString,
|
||||||
WS_GROUP | BS_AUTORADIOBUTTON | WS_CHILD,
|
WS_GROUP | BS_AUTORADIOBUTTON | WS_CHILD,
|
||||||
0, 0, 0, 0, hwndParent,
|
0, 0, 0, 0, GetHwnd(),
|
||||||
(HMENU)NewControlId(), wxGetInstance(), NULL);
|
(HMENU)NewControlId(), wxGetInstance(), NULL);
|
||||||
|
|
||||||
m_radioButtons->SetFont(GetFont());
|
m_radioButtons->SetFont(GetFont());
|
||||||
@@ -515,8 +512,8 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
|
|||||||
if (y == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
|
if (y == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
|
||||||
yy = currentY;
|
yy = currentY;
|
||||||
|
|
||||||
int y_offset = yy;
|
int y_offset = 0;
|
||||||
int x_offset = xx;
|
int x_offset = 0;
|
||||||
|
|
||||||
int cx1, cy1;
|
int cx1, cy1;
|
||||||
wxGetCharSize(m_hWnd, &cx1, &cy1, GetFont());
|
wxGetCharSize(m_hWnd, &cx1, &cy1, GetFont());
|
||||||
@@ -819,5 +816,55 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd,
|
|||||||
return ::CallWindowProc(CASTWNDPROC s_wndprocRadioBtn, hwnd, message, wParam, lParam);
|
return ::CallWindowProc(CASTWNDPROC s_wndprocRadioBtn, hwnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WXHRGN wxRadioBox::MSWCalculateClippingRegion()
|
||||||
|
{
|
||||||
|
RECT rc;
|
||||||
|
::GetWindowRect(GetHwnd(), &rc);
|
||||||
|
HRGN hrgn = ::CreateRectRgn(rc.left, rc.top, rc.right + 1, rc.bottom + 1);
|
||||||
|
|
||||||
|
size_t count = GetCount();
|
||||||
|
for ( size_t i = 0; i < count; ++i )
|
||||||
|
{
|
||||||
|
::GetWindowRect((*m_radioButtons)[i], &rc);
|
||||||
|
HRGN hrgnchild = ::CreateRectRgnIndirect(&rc);
|
||||||
|
::CombineRgn(hrgn, hrgn, hrgnchild, RGN_DIFF);
|
||||||
|
::DeleteObject(hrgnchild);
|
||||||
|
}
|
||||||
|
|
||||||
|
::GetWindowRect(GetHwnd(), &rc);
|
||||||
|
::OffsetRgn(hrgn, -rc.left, -rc.top);
|
||||||
|
|
||||||
|
return hrgn;
|
||||||
|
}
|
||||||
|
|
||||||
|
WXLRESULT wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
||||||
|
{
|
||||||
|
#ifndef __WXWINCE__
|
||||||
|
if ( nMsg == WM_PRINTCLIENT )
|
||||||
|
{
|
||||||
|
// first check to see if a parent window knows how to paint us better
|
||||||
|
for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
|
||||||
|
if ( win->MSWPrintChild(this, wParam, lParam) )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// nope, so lets do it ourselves
|
||||||
|
RECT rc;
|
||||||
|
WXHBRUSH hbr = DoMSWControlColor((HDC)wParam, wxNullColour);
|
||||||
|
if ( !hbr )
|
||||||
|
{
|
||||||
|
wxBrush *brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
|
||||||
|
hbr = (WXHBRUSH)brush->GetResourceHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
::GetClientRect(GetHwnd(), &rc);
|
||||||
|
::FillRect((HDC)wParam, &rc, (HBRUSH)hbr);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// __WXWINCE__
|
||||||
|
|
||||||
|
return wxStaticBox::MSWWindowProc(nMsg, wParam, lParam);
|
||||||
|
}
|
||||||
#endif // wxUSE_RADIOBOX
|
#endif // wxUSE_RADIOBOX
|
||||||
|
|
||||||
|
@@ -38,15 +38,10 @@
|
|||||||
#include "wx/statbox.h"
|
#include "wx/statbox.h"
|
||||||
#include "wx/notebook.h"
|
#include "wx/notebook.h"
|
||||||
#include "wx/sysopt.h"
|
#include "wx/sysopt.h"
|
||||||
|
#include "wx/image.h"
|
||||||
|
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
|
|
||||||
// under CE this style is not defined but we don't need to make static boxes
|
|
||||||
// transparent there neither
|
|
||||||
#ifndef WS_EX_TRANSPARENT
|
|
||||||
#define WS_EX_TRANSPARENT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxWin macros
|
// wxWin macros
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -103,6 +98,10 @@ wxCONSTRUCTOR_6( wxStaticBox , wxWindow* , Parent , wxWindowID , Id , wxString ,
|
|||||||
IMPLEMENT_DYNAMIC_CLASS(wxStaticBox, wxControl)
|
IMPLEMENT_DYNAMIC_CLASS(wxStaticBox, wxControl)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(wxStaticBox, wxControl)
|
||||||
|
EVT_PAINT(wxStaticBox::OnPaint)
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -132,8 +131,12 @@ WXDWORD wxStaticBox::MSWGetStyle(long style, WXDWORD *exstyle) const
|
|||||||
{
|
{
|
||||||
long styleWin = wxStaticBoxBase::MSWGetStyle(style, exstyle);
|
long styleWin = wxStaticBoxBase::MSWGetStyle(style, exstyle);
|
||||||
|
|
||||||
|
// no need for it anymore, must be removed for wxRadioBox child
|
||||||
|
// buttons to be able to repaint themselves
|
||||||
|
styleWin &= ~WS_CLIPCHILDREN;
|
||||||
|
|
||||||
if ( exstyle )
|
if ( exstyle )
|
||||||
*exstyle = WS_EX_TRANSPARENT;
|
*exstyle = 0;
|
||||||
|
|
||||||
return styleWin | BS_GROUPBOX;
|
return styleWin | BS_GROUPBOX;
|
||||||
}
|
}
|
||||||
@@ -194,5 +197,130 @@ void wxStaticBox::GetBordersForSizer(int *borderTop, int *borderOther) const
|
|||||||
#endif // !wxDIALOG_UNIT_COMPATIBILITY
|
#endif // !wxDIALOG_UNIT_COMPATIBILITY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rc must be in client coords!
|
||||||
|
void wxStaticBox::MSWClipBoxRegion(HRGN hrgn, const RECT *rc)
|
||||||
|
{
|
||||||
|
HRGN hrgnchild;
|
||||||
|
|
||||||
|
// top
|
||||||
|
hrgnchild = ::CreateRectRgn(0, 0, rc->right, 14);
|
||||||
|
::CombineRgn(hrgn, hrgn, hrgnchild, RGN_DIFF);
|
||||||
|
::DeleteObject(hrgnchild);
|
||||||
|
|
||||||
|
// bottom
|
||||||
|
hrgnchild = ::CreateRectRgn(0, rc->bottom - 7, rc->right, rc->bottom);
|
||||||
|
::CombineRgn(hrgn, hrgn, hrgnchild, RGN_DIFF);
|
||||||
|
::DeleteObject(hrgnchild);
|
||||||
|
|
||||||
|
// left
|
||||||
|
hrgnchild = ::CreateRectRgn(0, 0, 7, rc->bottom);
|
||||||
|
::CombineRgn(hrgn, hrgn, hrgnchild, RGN_DIFF);
|
||||||
|
::DeleteObject(hrgnchild);
|
||||||
|
|
||||||
|
// right
|
||||||
|
hrgnchild = ::CreateRectRgn(rc->right - 7, 0, rc->right, rc->bottom);
|
||||||
|
::CombineRgn(hrgn, hrgn, hrgnchild, RGN_DIFF);
|
||||||
|
::DeleteObject(hrgnchild);
|
||||||
|
}
|
||||||
|
|
||||||
|
WXHRGN wxStaticBox::MSWCalculateClippingRegion()
|
||||||
|
{
|
||||||
|
RECT rc;
|
||||||
|
::GetWindowRect(GetHwnd(), &rc);
|
||||||
|
HRGN hrgn = ::CreateRectRgn(rc.left, rc.top, rc.right + 1, rc.bottom + 1);
|
||||||
|
|
||||||
|
wxWindowList::compatibility_iterator node = GetParent()->GetChildren().GetFirst();
|
||||||
|
while ( node )
|
||||||
|
{
|
||||||
|
wxWindow *child = node->GetData();
|
||||||
|
|
||||||
|
// can't just test for (this != child) here since if a wxStaticBox
|
||||||
|
// overlaps another wxStaticBox then neither are drawn. The overlapping
|
||||||
|
// region will flicker but we shouldn't have overlapping windows anyway.
|
||||||
|
if ( !child->IsKindOf(CLASSINFO(wxStaticBox)) )
|
||||||
|
{
|
||||||
|
::GetWindowRect(GetHwndOf(child), &rc);
|
||||||
|
if ( RectInRegion(hrgn, &rc) )
|
||||||
|
{
|
||||||
|
// need to remove WS_CLIPSIBLINGS from all sibling windows
|
||||||
|
// that are within this staticbox if set
|
||||||
|
LONG style = ::GetWindowLong(GetHwndOf(child), GWL_STYLE);
|
||||||
|
if ( style & WS_CLIPSIBLINGS )
|
||||||
|
{
|
||||||
|
style &= ~WS_CLIPSIBLINGS;
|
||||||
|
::SetWindowLong(GetHwndOf(child), GWL_STYLE, style);
|
||||||
|
|
||||||
|
// MSDN: "If you have changed certain window data using
|
||||||
|
// SetWindowLong, you must call SetWindowPos to have the
|
||||||
|
// changes take effect."
|
||||||
|
::SetWindowPos(GetHwndOf(child), NULL, 0, 0, 0, 0,
|
||||||
|
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
|
||||||
|
SWP_FRAMECHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRGN hrgnchild = ::CreateRectRgnIndirect(&rc);
|
||||||
|
::CombineRgn(hrgn, hrgn, hrgnchild, RGN_DIFF);
|
||||||
|
::DeleteObject(hrgnchild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
::GetWindowRect(GetHwnd(), &rc);
|
||||||
|
::OffsetRgn(hrgn, -rc.left, -rc.top);
|
||||||
|
|
||||||
|
return hrgn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxStaticBox::OnPaint(wxPaintEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxPaintDC dc(this);
|
||||||
|
RECT rc;
|
||||||
|
::GetClientRect(GetHwnd(), &rc);
|
||||||
|
|
||||||
|
// paint the actual box
|
||||||
|
wxMemoryDC memdc;
|
||||||
|
wxBitmap bitmap(rc.right, rc.bottom);
|
||||||
|
memdc.SelectObject(bitmap);
|
||||||
|
|
||||||
|
// get bg brush
|
||||||
|
WXHBRUSH hbr = DoMSWControlColor(GetHdcOf(memdc), wxNullColour);
|
||||||
|
if ( !hbr )
|
||||||
|
{
|
||||||
|
wxBrush *brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
|
||||||
|
hbr = (WXHBRUSH)brush->GetResourceHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw solid box, but only blit the good bits
|
||||||
|
::FillRect(GetHdcOf(memdc), &rc, (HBRUSH)hbr);
|
||||||
|
MSWDefWindowProc(WM_PAINT, (WPARAM)GetHdcOf(memdc), 0);
|
||||||
|
|
||||||
|
// top
|
||||||
|
dc.Blit(7, 0, rc.right - 7, 14, &memdc, 7, 0);
|
||||||
|
// bottom
|
||||||
|
dc.Blit(7, rc.bottom - 7, rc.right - 7, rc.bottom, &memdc, 7, rc.bottom - 7);
|
||||||
|
// left
|
||||||
|
dc.Blit(0, 0, 7, rc.bottom, &memdc, 0, 0);
|
||||||
|
// right
|
||||||
|
dc.Blit(rc.right - 7, 0, rc.right, rc.bottom, &memdc, rc.right - 7, 0);
|
||||||
|
|
||||||
|
// paint the inner
|
||||||
|
HRGN hrgn = (HRGN)MSWCalculateClippingRegion();
|
||||||
|
// now remove the box itself
|
||||||
|
MSWClipBoxRegion(hrgn, &rc);
|
||||||
|
|
||||||
|
hbr = DoMSWControlColor(GetHdcOf(dc), wxNullColour);
|
||||||
|
if ( !hbr )
|
||||||
|
{
|
||||||
|
wxBrush *brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
|
||||||
|
hbr = (WXHBRUSH)brush->GetResourceHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
::SelectClipRgn(GetHdcOf(dc), hrgn);
|
||||||
|
::FillRect(GetHdcOf(dc), &rc, (HBRUSH)hbr);
|
||||||
|
::SelectClipRgn(GetHdcOf(dc), NULL);
|
||||||
|
::DeleteObject(hrgn);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_STATBOX
|
#endif // wxUSE_STATBOX
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user