+ m_window = window;
+
+ // do we have a DC for this window in the cache?
+ wxPaintDCInfo *info = FindInCache();
+ if ( info )
+ {
+ m_hDC = info->hdc;
+ info->count++;
+ }
+ else // not in cache, create a new one
+ {
+ // see comments in src/msw/window.cpp where this is defined
+ extern bool wxDidCreatePaintDC;
+
+ wxDidCreatePaintDC = true;
+
+ m_hDC = (WXHDC)::BeginPaint(GetHwndOf(m_window), &g_paintStruct);
+ if (m_hDC)
+ ms_cache.Add(new wxPaintDCInfo(m_window, this));
+ }
+
+ // Note: at this point m_hDC can be NULL under MicroWindows, when dragging.
+ if (!GetHDC())
+ return;
+
+ // (re)set the DC parameters.
+ InitDC();
+
+ // the HDC can have a clipping box (which we didn't set), make sure our
+ // DoGetClippingBox() checks for it
+ m_clipping = true;
+}
+
+wxPaintDCImpl::~wxPaintDCImpl()
+{
+ if ( m_hDC )
+ {
+ SelectOldObjects(m_hDC);
+
+ size_t index;
+ wxPaintDCInfo *info = FindInCache(&index);
+
+ wxCHECK_RET( info, wxT("existing DC should have a cache entry") );
+
+ if ( --info->count == 0 )
+ {
+ ::EndPaint(GetHwndOf(m_window), &g_paintStruct);
+
+ 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;
+ }
+}
+
+wxPaintDCInfo *wxPaintDCImpl::FindInCache(size_t *index) const
+{
+ wxPaintDCInfo *info = NULL;
+ size_t nCache = ms_cache.GetCount();
+ for ( size_t n = 0; n < nCache; n++ )
+ {
+ wxPaintDCInfo *info1 = &ms_cache[n];
+ if ( info1->hwnd == m_window->GetHWND() )
+ {
+ info = info1;
+ if ( index )
+ *index = n;
+ break;
+ }
+ }
+
+ return info;
+}
+
+// find the entry for this DC in the cache (keyed by the window)
+WXHDC wxPaintDCImpl::FindDCInCache(wxWindow* win)
+{
+ size_t nCache = ms_cache.GetCount();
+ for ( size_t n = 0; n < nCache; n++ )
+ {
+ wxPaintDCInfo *info = &ms_cache[n];
+ if ( info->hwnd == win->GetHWND() )
+ {
+ return info->hdc;
+ }
+ }
+ return 0;
+}
+
+/*
+ * wxPaintDCEx
+ */
+
+// TODO: don't duplicate wxPaintDCImpl code here!!
+
+class wxPaintDCExImpl: public wxPaintDCImpl
+{
+public:
+ wxPaintDCExImpl( wxDC *owner, wxWindow *window, WXHDC dc );
+ ~wxPaintDCExImpl();
+
+ int m_saveState;
+};
+
+
+IMPLEMENT_ABSTRACT_CLASS(wxPaintDCEx,wxPaintDC)
+
+wxPaintDCEx::wxPaintDCEx(wxWindow *window, WXHDC dc)
+ : wxPaintDC(new wxPaintDCExImpl(this, window, dc))