]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/dcclient.cpp
Change demo to not try to drop the table when it thinks it is creating it for the...
[wxWidgets.git] / src / os2 / dcclient.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: dcclient.cpp
3// Purpose: wxClientDC class
4// Author: David Webster
5// Modified by:
6// Created: 09/21/99
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#include "wx/string.h"
24#include "wx/log.h"
25#include "wx/window.h"
26
27#include "wx/os2/private.h"
28
29#include "wx/dcclient.h"
30
31// ----------------------------------------------------------------------------
32// array/list types
33// ----------------------------------------------------------------------------
34
35struct WXDLLEXPORT wxPaintDCInfo
36{
37 wxPaintDCInfo( wxWindow* pWin
38 ,wxDC* pDC
39 )
40 {
41 m_hWnd = pWin->GetHWND();
42 m_hDC = pDC->GetHDC();
43 m_nCount = 1;
44 }
45
46 WXHWND m_hWnd; // window for this DC
47 WXHDC m_hDC; // the DC handle
48 size_t m_nCount; // usage count
49}; // end of wxPaintDCInfot
50
51#include "wx/arrimpl.cpp"
52
53WX_DEFINE_OBJARRAY(wxArrayDCInfo);
54
55// ----------------------------------------------------------------------------
56// macros
57// ----------------------------------------------------------------------------
58
59 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
60 IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC)
61 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC)
62
63// ----------------------------------------------------------------------------
64// global variables
65// ----------------------------------------------------------------------------
66
67static RECT g_paintStruct;
68
69#ifdef __WXDEBUG__
70 // a global variable which we check to verify that wxPaintDC are only
71 // created in resopnse to WM_PAINT message - doing this from elsewhere is a
72 // common programming error among wxWindows programmers and might lead to
73 // very subtle and difficult to debug refresh/repaint bugs.
74 int g_isPainting = 0;
75#endif // __WXDEBUG__
76
77// ===========================================================================
78// implementation
79// ===========================================================================
80
81// ----------------------------------------------------------------------------
82// wxWindowDC
83// ----------------------------------------------------------------------------
84
85wxWindowDC::wxWindowDC()
86{
87 m_pCanvas = NULL;
88}
89
90wxWindowDC::wxWindowDC(
91 wxWindow* pTheCanvas
92)
93{
94 ERRORID vError;
95 wxString sError;
96
97 m_pCanvas = pTheCanvas;
98 m_hDC = (WXHDC) ::WinOpenWindowDC(GetWinHwnd(pTheCanvas) );
99
100 //
101 // default under PM is that Window and Client DC's are the same
102 // so we offer a separate Presentation Space to use for the
103 // entire window. Otherwise, calling BeginPaint will just create
104 // chached-micro client presentation space
105 //
106 m_hPS = ::GpiCreatePS( vHabmain
107 ,m_hDC
108 ,&m_PageSize
109 ,PU_PELS | GPIF_LONG | GPIA_ASSOC
110 );
111 ::GpiAssociate(m_hPS, NULLHANDLE);
112 ::GpiAssociate(m_hPS, m_hDC);
113
114 //
115 // Set the wxWindows color table
116 //
117 if (!::GpiCreateLogColorTable( m_hPS
118 ,0L
119 ,LCOLF_CONSECRGB
120 ,0L
121 ,(LONG)wxTheColourDatabase->m_nSize
122 ,(PLONG)wxTheColourDatabase->m_palTable
123 ))
124 {
125 vError = ::WinGetLastError(vHabmain);
126 sError = wxPMErrorToStr(vError);
127 wxLogError("Unable to set current color table. Error: %s\n", sError);
128 }
129 ::GpiCreateLogColorTable( m_hPS
130 ,0L
131 ,LCOLF_RGB
132 ,0L
133 ,0L
134 ,NULL
135 );
136 ::WinQueryWindowRect( GetWinHwnd(m_pCanvas)
137 ,&m_vRclPaint
138 );
139 InitDC();
140} // end of wxWindowDC::wxWindowDC
141
142void wxWindowDC::InitDC()
143{
144 //
145 // The background mode is only used for text background and is set in
146 // DrawText() to OPAQUE as required, otherwise always TRANSPARENT,
147 //
148 ::GpiSetBackMix(GetHPS(), BM_LEAVEALONE);
149
150 //
151 // Default bg colour is pne of the window
152 //
153 SetBackground(wxBrush(m_pCanvas->GetBackgroundColour(), wxSOLID));
154} // end of wxWindowDC::InitDC
155
156// ----------------------------------------------------------------------------
157// wxClientDC
158// ----------------------------------------------------------------------------
159
160wxClientDC::wxClientDC()
161{
162 m_pCanvas = NULL;
163}
164
165wxClientDC::wxClientDC(
166 wxWindow* pTheCanvas
167)
168{
169 SIZEL vSizl = { 0,0};
170 ERRORID vError;
171 wxString sError;
172
173 m_pCanvas = pTheCanvas;
174
175 //
176 // default under PM is that Window and Client DC's are the same
177 //
178 m_hDC = (WXHDC) ::WinOpenWindowDC(GetWinHwnd(pTheCanvas));
179 m_hPS = ::GpiCreatePS( wxGetInstance()
180 ,m_hDC
181 ,&vSizl
182 ,PU_PELS | GPIF_LONG | GPIA_ASSOC
183 );
184
185 // Set the wxWindows color table
186 if (!::GpiCreateLogColorTable( m_hPS
187 ,0L
188 ,LCOLF_CONSECRGB
189 ,0L
190 ,(LONG)wxTheColourDatabase->m_nSize
191 ,(PLONG)wxTheColourDatabase->m_palTable
192 ))
193 {
194 vError = ::WinGetLastError(vHabmain);
195 sError = wxPMErrorToStr(vError);
196 wxLogError("Unable to set current color table. Error: %s\n", sError);
197 }
198 ::GpiCreateLogColorTable( m_hPS
199 ,0L
200 ,LCOLF_RGB
201 ,0L
202 ,0L
203 ,NULL
204 );
205 //
206 // Set the DC/PS rectangle
207 //
208 ::WinQueryWindowRect( GetWinHwnd(m_pCanvas)
209 ,&m_vRclPaint
210 );
211 InitDC();
212} // end of wxClientDC::wxClientDC
213
214// ----------------------------------------------------------------------------
215// wxPaintDC
216// ----------------------------------------------------------------------------
217
218wxArrayDCInfo wxPaintDC::ms_cache;
219
220wxPaintDC::wxPaintDC()
221{
222 m_pCanvas = NULL;
223 m_hDC = 0;
224}
225
226wxPaintDC::wxPaintDC(
227 wxWindow* pCanvas
228)
229{
230 wxCHECK_RET(pCanvas, wxT("NULL canvas in wxPaintDC ctor"));
231
232#ifdef __WXDEBUG__
233 if (g_isPainting <= 0)
234 {
235 wxFAIL_MSG( wxT("wxPaintDC may be created only in EVT_PAINT handler!") );
236 return;
237 }
238#endif // __WXDEBUG__
239
240 m_pCanvas = pCanvas;
241
242 //
243 // Do we have a DC for this window in the cache?
244 //
245 wxPaintDCInfo* pInfo = FindInCache();
246
247 if (pInfo)
248 {
249 m_hDC = pInfo->m_hDC;
250 pInfo->m_nCount++;
251 }
252 else // not in cache, create a new one
253 {
254 HPS hPS;
255
256 hPS = ::WinBeginPaint( GetWinHwnd(m_pCanvas)
257 ,NULLHANDLE
258 ,&g_paintStruct
259 );
260 if(hPS)
261 {
262 m_hOldPS = m_hPS;
263 m_hPS = hPS;
264 ::GpiCreateLogColorTable( m_hPS
265 ,0L
266 ,LCOLF_CONSECRGB
267 ,0L
268 ,(LONG)wxTheColourDatabase->m_nSize
269 ,(PLONG)wxTheColourDatabase->m_palTable
270 );
271 ::GpiCreateLogColorTable( m_hPS
272 ,0L
273 ,LCOLF_RGB
274 ,0L
275 ,0L
276 ,NULL
277 );
278
279 ::WinFillRect(hPS, &g_paintStruct, m_pCanvas->GetBackgroundColour().GetPixel());
280 ::WinQueryWindowRect( GetWinHwnd(m_pCanvas)
281 ,&m_vRclPaint
282 );
283 }
284
285 m_bIsPaintTime = TRUE;
286 m_hDC = (WXHDC) -1; // to satisfy those anonizmous efforts
287 ms_cache.Add(new wxPaintDCInfo(m_pCanvas, this));
288 }
289 InitDC();
290} // end of wxPaintDC::wxPaintDC
291
292wxPaintDC::~wxPaintDC()
293{
294 if ( m_hDC )
295 {
296 SelectOldObjects(m_hDC);
297
298 size_t nIndex;
299 wxPaintDCInfo* pInfo = FindInCache(&nIndex);
300
301 wxCHECK_RET( pInfo, wxT("existing DC should have a cache entry") );
302
303 if ( !--pInfo->m_nCount )
304 {
305 ::WinEndPaint(m_hPS);
306 m_hPS = m_hOldPS;
307 m_bIsPaintTime = FALSE;
308 ms_cache.Remove(nIndex);
309 }
310 //else: cached DC entry is still in use
311
312 // prevent the base class dtor from ReleaseDC()ing it again
313 m_hDC = 0;
314 }
315}
316
317wxPaintDCInfo* wxPaintDC::FindInCache(
318 size_t* pIndex
319) const
320{
321 wxPaintDCInfo* pInfo = NULL;
322 size_t nCache = ms_cache.GetCount();
323
324 for (size_t n = 0; n < nCache; n++)
325 {
326 pInfo = &ms_cache[n];
327 if (pInfo->m_hWnd == m_pCanvas->GetHWND())
328 {
329 if (pIndex)
330 *pIndex = n;
331 break;
332 }
333 }
334 return pInfo;
335} // end of wxPaintDC::FindInCache
336
337// find the entry for this DC in the cache (keyed by the window)
338WXHDC wxPaintDC::FindDCInCache(
339 wxWindow* pWin
340)
341{
342 wxPaintDCInfo* pInfo = NULL;
343 size_t nCache = ms_cache.GetCount();
344
345 for (size_t n = 0; n < nCache; n++)
346 {
347 pInfo = &ms_cache[n];
348 if (pInfo->m_hWnd == pWin->GetHWND())
349 {
350 return pInfo->m_hDC;
351 }
352 }
353 return 0;
354} // end of wxPaintDC::FindInCache
355