1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxClientDC class 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // =========================================================================== 
  14 // =========================================================================== 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  23 #include "wx/string.h" 
  25 #include "wx/window.h" 
  28 #include "wx/os2/private.h" 
  30 #include "wx/dcclient.h" 
  32 // ---------------------------------------------------------------------------- 
  34 // ---------------------------------------------------------------------------- 
  36 struct WXDLLEXPORT wxPaintDCInfo
 
  38     wxPaintDCInfo( wxWindow
* pWin
 
  42         m_hWnd 
= pWin
->GetHWND(); 
  43         m_hDC 
= pDC
->GetHDC(); 
  47     WXHWND                          m_hWnd
;   // window for this DC 
  48     WXHDC                           m_hDC
;    // the DC handle 
  49     size_t                          m_nCount
; // usage count 
  50 }; // end of wxPaintDCInfot 
  52 #include "wx/arrimpl.cpp" 
  54 WX_DEFINE_OBJARRAY(wxArrayDCInfo
); 
  56 // ---------------------------------------------------------------------------- 
  58 // ---------------------------------------------------------------------------- 
  60     IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
) 
  61     IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
) 
  62     IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxWindowDC
) 
  64 // ---------------------------------------------------------------------------- 
  66 // ---------------------------------------------------------------------------- 
  68 static RECT        g_paintStruct
; 
  71     // a global variable which we check to verify that wxPaintDC are only 
  72     // created in resopnse to WM_PAINT message - doing this from elsewhere is a 
  73     // common programming error among wxWindows programmers and might lead to 
  74     // very subtle and difficult to debug refresh/repaint bugs. 
  78 // =========================================================================== 
  80 // =========================================================================== 
  82 // ---------------------------------------------------------------------------- 
  84 // ---------------------------------------------------------------------------- 
  86 wxWindowDC::wxWindowDC() 
  91 wxWindowDC::wxWindowDC( 
  98     m_pCanvas 
= pTheCanvas
; 
  99     m_hDC 
= (WXHDC
) ::WinOpenWindowDC(GetWinHwnd(pTheCanvas
) ); 
 102     // default under PM is that Window and Client DC's are the same 
 103     // so we offer a separate Presentation Space to use for the 
 104     // entire window.  Otherwise, calling BeginPaint will just create 
 105     // chached-micro client presentation space 
 107      m_hPS 
= ::GpiCreatePS( vHabmain
 
 110                            ,PU_PELS 
| GPIF_LONG 
| GPIA_ASSOC
 
 112     ::GpiAssociate(m_hPS
, NULLHANDLE
); 
 113     ::GpiAssociate(m_hPS
, m_hDC
); 
 116     // Set the wxWindows color table 
 118     if (!::GpiCreateLogColorTable( m_hPS
 
 122                                   ,(LONG
)wxTheColourDatabase
->m_nSize
 
 123                                   ,(PLONG
)wxTheColourDatabase
->m_palTable
 
 126         vError 
= ::WinGetLastError(vHabmain
); 
 127         sError 
= wxPMErrorToStr(vError
); 
 128         wxLogError("Unable to set current color table. Error: %s\n", sError
); 
 130     ::GpiCreateLogColorTable( m_hPS
 
 137     ::WinQueryWindowRect( GetWinHwnd(m_pCanvas
) 
 141 } // end of wxWindowDC::wxWindowDC 
 143 void wxWindowDC::InitDC() 
 147     vColor
.InitFromName("BLACK"); 
 148     m_pen
.SetColour(vColor
); 
 150     m_brush
.SetColour(vColor
); 
 152     // The background mode is only used for text background and is set in 
 153     // DrawText() to OPAQUE as required, otherwise always TRANSPARENT, 
 155     ::GpiSetBackMix(GetHPS(), BM_LEAVEALONE
); 
 158     // Default bg colour is pne of the window 
 160     SetBackground(wxBrush(m_pCanvas
->GetBackgroundColour(), wxSOLID
)); 
 161 } // end of wxWindowDC::InitDC 
 163 // ---------------------------------------------------------------------------- 
 165 // ---------------------------------------------------------------------------- 
 167 wxClientDC::wxClientDC() 
 172 wxClientDC::wxClientDC( 
 176     SIZEL                           vSizl 
= { 0,0}; 
 180     m_pCanvas 
= pTheCanvas
; 
 183     // default under PM is that Window and Client DC's are the same 
 185     m_hDC 
= (WXHDC
) ::WinOpenWindowDC(GetWinHwnd(pTheCanvas
)); 
 186     m_hPS 
= ::GpiCreatePS( wxGetInstance() 
 189                           ,PU_PELS 
| GPIF_LONG 
| GPIA_ASSOC
 
 192     // Set the wxWindows color table 
 193     if (!::GpiCreateLogColorTable( m_hPS
 
 197                                   ,(LONG
)wxTheColourDatabase
->m_nSize
 
 198                                   ,(PLONG
)wxTheColourDatabase
->m_palTable
 
 201         vError 
= ::WinGetLastError(vHabmain
); 
 202         sError 
= wxPMErrorToStr(vError
); 
 203         wxLogError("Unable to set current color table. Error: %s\n", sError
); 
 205     ::GpiCreateLogColorTable( m_hPS
 
 213     // Set the DC/PS rectangle 
 215     ::WinQueryWindowRect( GetWinHwnd(m_pCanvas
) 
 219 } // end of wxClientDC::wxClientDC 
 221 void wxClientDC::InitDC() 
 223     wxWindowDC::InitDC(); 
 225     // in wxUniv build we must manually do some DC adjustments usually 
 226     // performed by Windows for us 
 227 #ifdef __WXUNIVERSAL__ 
 228     wxPoint ptOrigin 
= m_canvas
->GetClientAreaOrigin(); 
 229     if ( ptOrigin
.x 
|| ptOrigin
.y 
) 
 231         // no need to shift DC origin if shift is null 
 232         SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
); 
 235     // clip the DC to avoid overwriting the non client area 
 236     SetClippingRegion(wxPoint(0, 0), m_canvas
->GetClientSize()); 
 237 #endif // __WXUNIVERSAL__ 
 238 } // end of wxClientDC::InitDC 
 240 wxClientDC::~wxClientDC() 
 242 } // end of wxClientDC::~wxClientDC 
 244 // ---------------------------------------------------------------------------- 
 246 // ---------------------------------------------------------------------------- 
 248 wxArrayDCInfo 
wxPaintDC::ms_cache
; 
 250 wxPaintDC::wxPaintDC() 
 256 wxPaintDC::wxPaintDC( 
 260     wxCHECK_RET(pCanvas
, wxT("NULL canvas in wxPaintDC ctor")); 
 263     if (g_isPainting 
<= 0) 
 265         wxFAIL_MSG( wxT("wxPaintDC may be created only in EVT_PAINT handler!") ); 
 268 #endif // __WXDEBUG__ 
 273     // Do we have a DC for this window in the cache? 
 275     wxPaintDCInfo
*                  pInfo 
= FindInCache(); 
 279         m_hDC 
= pInfo
->m_hDC
; 
 282     else // not in cache, create a new one 
 286         hPS 
= ::WinBeginPaint( GetWinHwnd(m_pCanvas
) 
 294             ::GpiCreateLogColorTable( m_hPS
 
 298                                      ,(LONG
)wxTheColourDatabase
->m_nSize
 
 299                                      ,(PLONG
)wxTheColourDatabase
->m_palTable
 
 301             ::GpiCreateLogColorTable( m_hPS
 
 309             ::WinFillRect(hPS
, &g_paintStruct
,  m_pCanvas
->GetBackgroundColour().GetPixel()); 
 310             ::WinQueryWindowRect( GetWinHwnd(m_pCanvas
) 
 315         m_bIsPaintTime   
= TRUE
; 
 316         m_hDC 
= (WXHDC
) -1; // to satisfy those anonizmous efforts 
 317         ms_cache
.Add(new wxPaintDCInfo(m_pCanvas
, this)); 
 320 } // end of wxPaintDC::wxPaintDC 
 322 wxPaintDC::~wxPaintDC() 
 326         SelectOldObjects(m_hDC
); 
 329         wxPaintDCInfo
*              pInfo 
= FindInCache(&nIndex
); 
 331         wxCHECK_RET( pInfo
, wxT("existing DC should have a cache entry") ); 
 333         if ( !--pInfo
->m_nCount 
) 
 335             ::WinEndPaint(m_hPS
); 
 337             m_bIsPaintTime 
= FALSE
; 
 338             ms_cache
.RemoveAt(nIndex
); 
 340         //else: cached DC entry is still in use 
 342         // prevent the base class dtor from ReleaseDC()ing it again 
 347 wxPaintDCInfo
* wxPaintDC::FindInCache( 
 351     wxPaintDCInfo
*                  pInfo 
= NULL
; 
 352     size_t                          nCache 
= ms_cache
.GetCount(); 
 354     for (size_t n 
= 0; n 
< nCache
; n
++) 
 356         pInfo 
= &ms_cache
[n
]; 
 357         if (pInfo
->m_hWnd 
== m_pCanvas
->GetHWND()) 
 365 } // end of wxPaintDC::FindInCache 
 367 // find the entry for this DC in the cache (keyed by the window) 
 368 WXHDC 
wxPaintDC::FindDCInCache( 
 372     wxPaintDCInfo
*                  pInfo 
= NULL
; 
 373     size_t                          nCache 
= ms_cache
.GetCount(); 
 375     for (size_t n 
= 0; n 
< nCache
; n
++) 
 377         pInfo 
= &ms_cache
[n
]; 
 378         if (pInfo
->m_hWnd 
== pWin
->GetHWND()) 
 384 } // end of wxPaintDC::FindInCache