From c6151f2a94c8851e712755839106707a863c5449 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Tue, 29 Jul 2003 14:27:18 +0000 Subject: [PATCH] Added wxPaintDCEx class, to handle the case where an HDC is passed with WM_PAINT. Apps that want to can have their own HDC painted on. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22367 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/dcclient.h | 18 +++++++++++++ src/msw/crashrpt.cpp | 9 ++++++- src/msw/dcclient.cpp | 54 +++++++++++++++++++++++++++++++++++++++ src/msw/window.cpp | 13 ++++++++-- 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/include/wx/msw/dcclient.h b/include/wx/msw/dcclient.h index 48ee0851d0..bad4cf72f2 100644 --- a/include/wx/msw/dcclient.h +++ b/include/wx/msw/dcclient.h @@ -100,5 +100,23 @@ private: DECLARE_DYNAMIC_CLASS_NO_COPY(wxPaintDC) }; +/* + * wxPaintDCEx + * This class is used when an application sends an HDC with the WM_PAINT + * message. It is used in HandlePaint and need not be used by an application. + */ + +class WXDLLEXPORT wxPaintDCEx : public wxPaintDC +{ +public: + wxPaintDCEx(wxWindow *canvas, WXHDC dc); + virtual ~wxPaintDCEx(); +private: + int saveState; + + DECLARE_CLASS(wxPaintDCEx) + DECLARE_NO_COPY_CLASS(wxPaintDCEx) +}; + #endif // _WX_DCCLIENT_H_ diff --git a/src/msw/crashrpt.cpp b/src/msw/crashrpt.cpp index eaccaeafce..9ddcf49029 100644 --- a/src/msw/crashrpt.cpp +++ b/src/msw/crashrpt.cpp @@ -997,7 +997,14 @@ wxString wxCrashReportImpl::GetExceptionString(DWORD dwCode) #endif // wxUSE_DBGHELP -bool wxCrashReportImpl::Generate(int flags) +// Remove warning +#if wxUSE_DBGHELP +#define _WXUNUSED(x) x +#else +#define _WXUNUSED WXUNUSED +#endif + +bool wxCrashReportImpl::Generate(int _WXUNUSED(flags)) { if ( m_hFile == INVALID_HANDLE_VALUE ) return false; diff --git a/src/msw/dcclient.cpp b/src/msw/dcclient.cpp index c03897cf2a..748fe83850 100644 --- a/src/msw/dcclient.cpp +++ b/src/msw/dcclient.cpp @@ -65,6 +65,7 @@ WX_DEFINE_OBJARRAY(wxArrayDCInfo); IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC) IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxClientDC) +IMPLEMENT_CLASS(wxPaintDCEx, wxPaintDC) // ---------------------------------------------------------------------------- // global variables @@ -305,3 +306,56 @@ WXHDC wxPaintDC::FindDCInCache(wxWindow* win) return 0; } +/* + * wxPaintDCEx + */ + +wxPaintDCEx::wxPaintDCEx(wxWindow *canvas, WXHDC dc) : saveState(0) +{ +#ifdef __WXDEBUG__ + if ( !dc ) + { + wxFAIL_MSG( wxT("wxPaintDCEx requires an existing device context") ); + return; + } +#endif // __WXDEBUG__ + + m_canvas = canvas; + + wxPaintDCInfo *info = FindInCache(); + if ( info ) + { + m_hDC = info->hdc; + info->count++; + } + else // not in cache, create a new one + { + m_hDC = dc; + ms_cache.Add(new wxPaintDCInfo(m_canvas, this)); + saveState = SaveDC((HDC) dc); + } +} + +wxPaintDCEx::~wxPaintDCEx() +{ + size_t index; + wxPaintDCInfo *info = FindInCache(&index); + + wxCHECK_RET( info, wxT("existing DC should have a cache entry") ); + + if ( !--info->count ) + { + RestoreDC((HDC) m_hDC, saveState); + ms_cache.RemoveAt(index); + + // Reduce the number of bogus reports of non-freed memory + // at app exit + if (ms_cache.IsEmpty()) + ms_cache.Clear(); + } + //else: cached DC entry is still in use + + // prevent the base class dtor from ReleaseDC()ing it again + m_hDC = 0; +} + diff --git a/src/msw/window.cpp b/src/msw/window.cpp index e17c2ef59e..a9f4e8312e 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -2344,8 +2344,17 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam break; case WM_PAINT: - processed = HandlePaint(); - break; + { + wxPaintDCEx *pdc = 0; + if (wParam) { + pdc = new wxPaintDCEx(this, (WXHDC) wParam); + } + processed = HandlePaint(); + if (pdc) { + delete pdc; + } + break; + } case WM_CLOSE: #ifdef __WXUNIVERSAL__