+// This subclass contains information for the HDCs we receive from outside, as
+// WPARAM of WM_PAINT itself.
+class wxPaintDCInfoExternal : public wxPaintDCInfo
+{
+public:
+ wxPaintDCInfoExternal(HDC hdc)
+ : wxPaintDCInfo(hdc),
+ m_state(::SaveDC(hdc))
+ {
+ }
+
+ virtual ~wxPaintDCInfoExternal()
+ {
+ ::RestoreDC(m_hdc, m_state);
+ }
+
+private:
+ const int m_state;
+
+ wxDECLARE_NO_COPY_CLASS(wxPaintDCInfoExternal);
+};
+
+// The global map containing HDC to use for the given window. The entries in
+// this map only exist during WM_PAINT processing and are destroyed when it is
+// over.
+//
+// It is needed because in some circumstances it can happen that more than one
+// wxPaintDC is created for the same window during its WM_PAINT handling (and
+// as this can happen implicitly, e.g. by calling a function in some library,
+// this can be quite difficult to find) but we need to reuse the same HDC for
+// all of them because we can't call BeginPaint() more than once. So we cache
+// the first HDC created for the window in this map and then reuse it later if
+// needed. And, of course, remove it from the map when the painting is done.
+WX_DECLARE_HASH_MAP(wxWindow *, wxPaintDCInfo *,
+ wxPointerHash, wxPointerEqual,
+ PaintDCInfos);
+
+PaintDCInfos gs_PaintDCInfos;
+
+} // anonymous namespace
+
+// ----------------------------------------------------------------------------
+// global variables
+// ----------------------------------------------------------------------------
+
+#ifdef wxHAS_PAINT_DEBUG
+ // a global variable which we check to verify that wxPaintDC are only
+ // created in response to WM_PAINT message - doing this from elsewhere is a
+ // common programming error among wxWidgets programmers and might lead to
+ // very subtle and difficult to debug refresh/repaint bugs.
+ int g_isPainting = 0;
+#endif // wxHAS_PAINT_DEBUG
+
+// ===========================================================================
+// implementation
+// ===========================================================================
+
+// ----------------------------------------------------------------------------
+// wxMSWWindowDCImpl
+// ----------------------------------------------------------------------------
+
+IMPLEMENT_ABSTRACT_CLASS(wxWindowDCImpl, wxMSWDCImpl)
+
+wxWindowDCImpl::wxWindowDCImpl( wxDC *owner ) :
+ wxMSWDCImpl( owner )
+{
+}
+
+wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *window ) :
+ wxMSWDCImpl( owner )
+{
+ wxCHECK_RET( window, wxT("invalid window in wxWindowDCImpl") );
+
+ m_window = window;
+ m_hDC = (WXHDC) ::GetWindowDC(GetHwndOf(m_window));
+
+ // m_bOwnsDC was already set to false in the base class ctor, so the DC
+ // will be released (and not deleted) in ~wxDC
+ InitDC();
+}
+
+void wxWindowDCImpl::InitDC()
+{
+ // the background mode is only used for text background and is set in
+ // DrawText() to OPAQUE as required, otherwise always TRANSPARENT,
+ ::SetBkMode(GetHdc(), TRANSPARENT);