]> git.saurik.com Git - wxWidgets.git/blob - src/msw/dcclient.cpp
1. more (minor) wxCaret bug fixes
[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/dcclient.h"
32 #include "wx/log.h"
33
34 #include "wx/msw/private.h"
35
36 // ----------------------------------------------------------------------------
37 // macros
38 // ----------------------------------------------------------------------------
39
40 #if !USE_SHARED_LIBRARY
41 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
42 IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC)
43 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC)
44 #endif
45
46 // ----------------------------------------------------------------------------
47 // global variables
48 // ----------------------------------------------------------------------------
49
50 static PAINTSTRUCT g_paintStruct;
51
52 #ifdef __WXDEBUG__
53 // a global variable which we check to verify that wxPaintDC are only
54 // created in resopnse to WM_PAINT message - doing this from elsewhere is a
55 // common programming error among wxWindows programmers and might lead to
56 // very subtle and difficult to debug refresh/repaint bugs.
57 extern bool g_isPainting = FALSE;
58 #endif // __WXDEBUG__
59
60 // ===========================================================================
61 // implementation
62 // ===========================================================================
63
64 // ----------------------------------------------------------------------------
65 // wxWindowDC
66 // ----------------------------------------------------------------------------
67
68 wxWindowDC::wxWindowDC()
69 {
70 m_canvas = NULL;
71 }
72
73 wxWindowDC::wxWindowDC(wxWindow *the_canvas)
74 {
75 m_canvas = the_canvas;
76 m_hDC = (WXHDC) ::GetWindowDC(GetWinHwnd(the_canvas) );
77 m_hDCCount++;
78
79 SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID));
80 }
81
82 wxWindowDC::~wxWindowDC()
83 {
84 if (m_canvas && m_hDC)
85 {
86 SelectOldObjects(m_hDC);
87
88 ::ReleaseDC(GetWinHwnd(m_canvas), GetHdc());
89 m_hDC = 0;
90 }
91
92 m_hDCCount--;
93 }
94
95 // ----------------------------------------------------------------------------
96 // wxClientDC
97 // ----------------------------------------------------------------------------
98
99 wxClientDC::wxClientDC()
100 {
101 m_canvas = NULL;
102 }
103
104 wxClientDC::wxClientDC(wxWindow *the_canvas)
105 {
106 m_canvas = the_canvas;
107 m_hDC = (WXHDC) ::GetDC(GetWinHwnd(the_canvas));
108
109 SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID));
110 }
111
112 wxClientDC::~wxClientDC()
113 {
114 if ( m_canvas && GetHdc() )
115 {
116 SelectOldObjects(m_hDC);
117
118 ::ReleaseDC(GetWinHwnd(m_canvas), GetHdc());
119 m_hDC = 0;
120 }
121 }
122
123 // ----------------------------------------------------------------------------
124 // wxPaintDC
125 // ----------------------------------------------------------------------------
126
127 // TODO (VZ) I have still some doubts about this hack and I still think that we
128 // should store pairs of (hwnd, hdc) and not just the DC - what if
129 // BeginPaint() was called on other window? It seems to work like
130 // this, but to be sure about it we'd need to store hwnd too...
131
132 WXHDC wxPaintDC::ms_PaintHDC = 0;
133 size_t wxPaintDC::ms_PaintCount = 0; // count of ms_PaintHDC usage
134
135 wxPaintDC::wxPaintDC()
136 {
137 m_canvas = NULL;
138 }
139
140 wxPaintDC::wxPaintDC(wxWindow *canvas)
141 {
142 wxCHECK_RET( canvas, "NULL canvas in wxPaintDC ctor" );
143 wxCHECK_RET( g_isPainting,
144 _T("wxPaintDC may be created only in EVT_PAINT handler!") );
145
146 m_canvas = canvas;
147
148 // Don't call Begin/EndPaint if it's already been called: for example, if
149 // calling a base class OnPaint.
150 if ( ms_PaintCount > 0 ) {
151 // it means that we've already called BeginPaint and so we must just
152 // reuse the same HDC (BeginPaint shouldn't be called more than once)
153 wxASSERT( ms_PaintHDC );
154
155 m_hDC = ms_PaintHDC;
156 ms_PaintCount++;
157 }
158 else {
159 ms_PaintHDC =
160 m_hDC = (WXHDC)::BeginPaint((HWND)m_canvas->GetHWND(), &g_paintStruct);
161 ms_PaintCount = 1;
162 m_hDCCount++;
163 }
164
165 SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID));
166 }
167
168 wxPaintDC::~wxPaintDC()
169 {
170 if ( m_hDC ) {
171 if ( !--ms_PaintCount ) {
172 ::EndPaint((HWND)m_canvas->GetHWND(), &g_paintStruct);
173 m_hDCCount--;
174 m_hDC = (WXHDC) NULL;
175 ms_PaintHDC = (WXHDC) NULL;
176 }
177 //else: ms_PaintHDC still in use
178 }
179 }
180