1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxClientDC class
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "dcclient.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
31 #include "wx/string.h"
33 #include "wx/window.h"
35 #include "wx/msw/private.h"
37 #include "wx/dcclient.h"
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 #if !USE_SHARED_LIBRARY
44 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
45 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
46 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxWindowDC
)
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 static PAINTSTRUCT g_paintStruct
;
56 // a global variable which we check to verify that wxPaintDC are only
57 // created in resopnse to WM_PAINT message - doing this from elsewhere is a
58 // common programming error among wxWindows programmers and might lead to
59 // very subtle and difficult to debug refresh/repaint bugs.
60 extern bool g_isPainting
= FALSE
;
63 // ===========================================================================
65 // ===========================================================================
67 // ----------------------------------------------------------------------------
69 // ----------------------------------------------------------------------------
71 wxWindowDC::wxWindowDC()
76 wxWindowDC::wxWindowDC(wxWindow
*the_canvas
)
78 m_canvas
= the_canvas
;
79 m_hDC
= (WXHDC
) ::GetWindowDC(GetWinHwnd(the_canvas
) );
82 SetBackground(wxBrush(m_canvas
->GetBackgroundColour(), wxSOLID
));
85 wxWindowDC::~wxWindowDC()
87 if (m_canvas
&& m_hDC
)
89 SelectOldObjects(m_hDC
);
91 ::ReleaseDC(GetWinHwnd(m_canvas
), GetHdc());
98 // ----------------------------------------------------------------------------
100 // ----------------------------------------------------------------------------
102 wxClientDC::wxClientDC()
107 wxClientDC::wxClientDC(wxWindow
*the_canvas
)
109 m_canvas
= the_canvas
;
110 m_hDC
= (WXHDC
) ::GetDC(GetWinHwnd(the_canvas
));
112 SetBackground(wxBrush(m_canvas
->GetBackgroundColour(), wxSOLID
));
115 wxClientDC::~wxClientDC()
117 if ( m_canvas
&& GetHdc() )
119 SelectOldObjects(m_hDC
);
121 ::ReleaseDC(GetWinHwnd(m_canvas
), GetHdc());
126 // ----------------------------------------------------------------------------
128 // ----------------------------------------------------------------------------
130 // TODO (VZ) I have still some doubts about this hack and I still think that we
131 // should store pairs of (hwnd, hdc) and not just the DC - what if
132 // BeginPaint() was called on other window? It seems to work like
133 // this, but to be sure about it we'd need to store hwnd too...
135 WXHDC
wxPaintDC::ms_PaintHDC
= 0;
136 size_t wxPaintDC::ms_PaintCount
= 0; // count of ms_PaintHDC usage
138 wxPaintDC::wxPaintDC()
143 wxPaintDC::wxPaintDC(wxWindow
*canvas
)
145 wxCHECK_RET( canvas
, "NULL canvas in wxPaintDC ctor" );
148 wxCHECK_RET( g_isPainting
, _T("wxPaintDC may be created only in EVT_PAINT handler!") );
153 // Don't call Begin/EndPaint if it's already been called: for example, if
154 // calling a base class OnPaint.
155 if ( ms_PaintCount
> 0 ) {
156 // it means that we've already called BeginPaint and so we must just
157 // reuse the same HDC (BeginPaint shouldn't be called more than once)
158 wxASSERT( ms_PaintHDC
);
165 m_hDC
= (WXHDC
)::BeginPaint((HWND
)m_canvas
->GetHWND(), &g_paintStruct
);
170 SetBackground(wxBrush(m_canvas
->GetBackgroundColour(), wxSOLID
));
173 wxPaintDC::~wxPaintDC()
176 if ( !--ms_PaintCount
) {
177 ::EndPaint((HWND
)m_canvas
->GetHWND(), &g_paintStruct
);
179 m_hDC
= (WXHDC
) NULL
;
180 ms_PaintHDC
= (WXHDC
) NULL
;
182 //else: ms_PaintHDC still in use