]> git.saurik.com Git - wxWidgets.git/blob - src/msw/dcclient.cpp
e29e8b472fb0cbe85948fd7ad1792d528bd5f9e6
[wxWidgets.git] / src / msw / dcclient.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dcclient.cpp
3 // Purpose: wxClientDC class
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 01/02/97
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ===========================================================================
13 // declarations
14 // ===========================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "dcclient.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #include "wx/string.h"
32 #include "wx/log.h"
33 #include "wx/window.h"
34
35 #include "wx/msw/private.h"
36
37 #include "wx/dcclient.h"
38
39 // ----------------------------------------------------------------------------
40 // macros
41 // ----------------------------------------------------------------------------
42
43 #if !USE_SHARED_LIBRARY
44 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
45 IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC)
46 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC)
47 #endif
48
49 // ----------------------------------------------------------------------------
50 // global variables
51 // ----------------------------------------------------------------------------
52
53 static PAINTSTRUCT g_paintStruct;
54
55 #ifdef __WXDEBUG__
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;
61 #endif // __WXDEBUG__
62
63 // ===========================================================================
64 // implementation
65 // ===========================================================================
66
67 // ----------------------------------------------------------------------------
68 // wxWindowDC
69 // ----------------------------------------------------------------------------
70
71 wxWindowDC::wxWindowDC()
72 {
73 m_canvas = NULL;
74 }
75
76 wxWindowDC::wxWindowDC(wxWindow *the_canvas)
77 {
78 m_canvas = the_canvas;
79 m_hDC = (WXHDC) ::GetWindowDC(GetWinHwnd(the_canvas) );
80 m_hDCCount++;
81
82 SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID));
83 }
84
85 wxWindowDC::~wxWindowDC()
86 {
87 if (m_canvas && m_hDC)
88 {
89 SelectOldObjects(m_hDC);
90
91 ::ReleaseDC(GetWinHwnd(m_canvas), GetHdc());
92 m_hDC = 0;
93 }
94
95 m_hDCCount--;
96 }
97
98 // ----------------------------------------------------------------------------
99 // wxClientDC
100 // ----------------------------------------------------------------------------
101
102 wxClientDC::wxClientDC()
103 {
104 m_canvas = NULL;
105 }
106
107 wxClientDC::wxClientDC(wxWindow *the_canvas)
108 {
109 m_canvas = the_canvas;
110 m_hDC = (WXHDC) ::GetDC(GetWinHwnd(the_canvas));
111
112 SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID));
113 }
114
115 wxClientDC::~wxClientDC()
116 {
117 if ( m_canvas && GetHdc() )
118 {
119 SelectOldObjects(m_hDC);
120
121 ::ReleaseDC(GetWinHwnd(m_canvas), GetHdc());
122 m_hDC = 0;
123 }
124 }
125
126 // ----------------------------------------------------------------------------
127 // wxPaintDC
128 // ----------------------------------------------------------------------------
129
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...
134
135 WXHDC wxPaintDC::ms_PaintHDC = 0;
136 size_t wxPaintDC::ms_PaintCount = 0; // count of ms_PaintHDC usage
137
138 wxPaintDC::wxPaintDC()
139 {
140 m_canvas = NULL;
141 }
142
143 wxPaintDC::wxPaintDC(wxWindow *canvas)
144 {
145 wxCHECK_RET( canvas, "NULL canvas in wxPaintDC ctor" );
146
147 #ifdef __WXDEBUG__
148 wxCHECK_RET( g_isPainting, _T("wxPaintDC may be created only in EVT_PAINT handler!") );
149 #endif
150
151 m_canvas = canvas;
152
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 );
159
160 m_hDC = ms_PaintHDC;
161 ms_PaintCount++;
162 }
163 else {
164 ms_PaintHDC =
165 m_hDC = (WXHDC)::BeginPaint((HWND)m_canvas->GetHWND(), &g_paintStruct);
166 ms_PaintCount = 1;
167 m_hDCCount++;
168 }
169
170 SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID));
171 }
172
173 wxPaintDC::~wxPaintDC()
174 {
175 if ( m_hDC ) {
176 if ( !--ms_PaintCount ) {
177 ::EndPaint((HWND)m_canvas->GetHWND(), &g_paintStruct);
178 m_hDCCount--;
179 m_hDC = (WXHDC) NULL;
180 ms_PaintHDC = (WXHDC) NULL;
181 }
182 //else: ms_PaintHDC still in use
183 }
184 }
185