From 5230934a95bf9b3112ec2a7e070e8cbb4cea7f55 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 2 Feb 2002 00:40:45 +0000 Subject: [PATCH] wxDC::SetClippingRegion() in wxMSW works like in wxGTK, i.e. combines the given region with the old one (also documented this behaviour as the correct one) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13967 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 3 ++ docs/latex/wx/dc.tex | 16 +++++++-- include/wx/msw/dc.h | 3 ++ src/msw/dc.cpp | 77 +++++++++++++++++++++++++++----------------- 4 files changed, 67 insertions(+), 32 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 4cdb6bdaad..a25333f67f 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -57,6 +57,9 @@ wxMSW: style to avoid it, wxFRAME_FLOAT_ON_PARENT style is now obsolete and has no effect +- all overloads of wxDC::SetClippingRegion() combine the given region with the + previously selected one instead of replacing it + Unix ports: - You should use `wx-config --cxxflags` in your makefiles instead of diff --git a/docs/latex/wx/dc.tex b/docs/latex/wx/dc.tex index 0dc9eed9a0..f756cd292a 100644 --- a/docs/latex/wx/dc.tex +++ b/docs/latex/wx/dc.tex @@ -788,11 +788,21 @@ whether text will be drawn with a background colour or not. \func{void}{SetClippingRegion}{\param{wxCoord}{ x}, \param{wxCoord}{ y}, \param{wxCoord}{ width}, \param{wxCoord}{ height}} +\func{void}{SetClippingRegion}{\param{const wxPoint\& }{pt}, \param{const wxSize\& }{sz}} + +\func{void}{SetClippingRegion}{\param{const wxRect\&}{ rect}} + \func{void}{SetClippingRegion}{\param{const wxRegion\&}{ region}} -Sets the clipping region for the DC. The clipping region is an area -to which drawing is restricted. Possible uses for the clipping region are for clipping text -or for speeding up window redraws when only a known area of the screen is damaged. +Sets the clipping region for this device context to the intersection of the +given region described by the parameters of this method and the previously set +clipping region. You should call +\helpref{DestroyClippingRegion}{wxdcdestroyclippingregion} if you want to set +the clipping region exactly to the region specified. + +The clipping region is an area to which drawing is restricted. Possible uses +for the clipping region are for clipping text or for speeding up window redraws +when only a known area of the screen is damaged. \wxheading{See also} diff --git a/include/wx/msw/dc.h b/include/wx/msw/dc.h index 30f79932f5..bdb94b9116 100644 --- a/include/wx/msw/dc.h +++ b/include/wx/msw/dc.h @@ -235,6 +235,9 @@ protected: // common part of DoDrawText() and DoDrawRotatedText() void DrawAnyText(const wxString& text, wxCoord x, wxCoord y); + // common part of DoSetClippingRegion() and DoSetClippingRegionAsRegion() + void SetClippingHrgn(WXHRGN hrgn); + // MSW-specific member variables int m_windowExtX; int m_windowExtY; diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 406f0f2a1e..c222cbbf4c 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -279,7 +279,7 @@ void wxDC::UpdateClipBox() #endif RECT rect; - GetClipBox(GetHdc(), &rect); + ::GetClipBox(GetHdc(), &rect); m_clipX1 = (wxCoord) XDEV2LOG(rect.left); m_clipY1 = (wxCoord) YDEV2LOG(rect.top); @@ -287,14 +287,50 @@ void wxDC::UpdateClipBox() m_clipY2 = (wxCoord) YDEV2LOG(rect.bottom); } -void wxDC::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h) +// common part of DoSetClippingRegion() and DoSetClippingRegionAsRegion() +void wxDC::SetClippingHrgn(WXHRGN hrgn) { + wxCHECK_RET( hrgn, wxT("invalid clipping region") ); + #ifdef __WXMICROWIN__ - if (!GetHDC()) return; -#endif + if (!GetHdc()) return; +#endif // __WXMICROWIN__ + + // note that we combine the new clipping region with the existing one: this + // is compatible with what the other ports do and is the documented + // behaviour now (starting with 2.3.3) +#ifdef __WIN16__ + RECT rectClip; + if ( !::GetClipBox(GetHdc(), &rectClip) ) + return; + + HRGN hrgnDest = ::CreateRectRgn(0, 0, 0, 0); + HRGN hrgnClipOld = ::CreateRectRgn(rectClip.left, rectClip.top, + rectClip.right, rectClip.bottom); + + if ( ::CombineRgn(hrgnDest, hrgnClipOld, (HRGN)hrgn, RGN_AND) != ERROR ) + { + ::SelectClipRgn(GetHdc(), hrgnDest); + } + + ::DeleteObject(hrgnClipOld); + ::DeleteObject(hrgnDest); +#else // Win32 + if ( ::ExtSelectClipRgn(GetHdc(), (HRGN)hrgn, RGN_AND) == ERROR ) + { + wxLogLastError(_T("ExtSelectClipRgn")); + + return; + } +#endif // Win16/32 m_clipping = TRUE; + UpdateClipBox(); +} + +void wxDC::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h) +{ // the region coords are always the device ones, so do the translation // manually // @@ -309,33 +345,15 @@ void wxDC::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h) } else { - if ( ::SelectClipRgn(GetHdc(), hrgn) == ERROR ) - { - wxLogLastError(_T("SelectClipRgn")); - } - DeleteObject(hrgn); + SetClippingHrgn((WXHRGN)hrgn); - UpdateClipBox(); + ::DeleteObject(hrgn); } } void wxDC::DoSetClippingRegionAsRegion(const wxRegion& region) { -#ifdef __WXMICROWIN__ - if (!GetHDC()) return; -#endif - - wxCHECK_RET( GetHrgnOf(region), wxT("invalid clipping region") ); - - m_clipping = TRUE; - -#ifdef __WIN16__ - SelectClipRgn(GetHdc(), GetHrgnOf(region)); -#else // Win32 - ExtSelectClipRgn(GetHdc(), GetHrgnOf(region), RGN_AND); -#endif // Win16/32 - - UpdateClipBox(); + SetClippingHrgn(region.GetHRGN()); } void wxDC::DestroyClippingRegion() @@ -347,11 +365,12 @@ void wxDC::DestroyClippingRegion() if (m_clipping && m_hDC) { // TODO: this should restore the previous clipping region, - // so that OnPaint processing works correctly, and the update clipping region - // doesn't get destroyed after the first DestroyClippingRegion. + // so that OnPaint processing works correctly, and the update + // clipping region doesn't get destroyed after the first + // DestroyClippingRegion. HRGN rgn = CreateRectRgn(0, 0, 32000, 32000); - SelectClipRgn(GetHdc(), rgn); - DeleteObject(rgn); + ::SelectClipRgn(GetHdc(), rgn); + ::DeleteObject(rgn); } m_clipping = FALSE; -- 2.45.2