home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK10 / MFC / SRC / WINGDI.CP$ / wingdi
Encoding:
Text File  |  1992-03-10  |  7.9 KB  |  375 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library. 
  2. // Copyright (C) 1992 Microsoft Corporation 
  3. // All rights reserved. 
  4. //  
  5. // This source code is only intended as a supplement to the 
  6. // Microsoft Foundation Classes Reference and Microsoft 
  7. // QuickHelp documentation provided with the library. 
  8. // See these sources for detailed information regarding the 
  9. // Microsoft Foundation Classes product. 
  10.  
  11.  
  12. #include "afxwin.h"
  13. #pragma hdrstop
  14.  
  15. #include "winhand_.h"
  16.  
  17. #ifdef AFX_CORE_SEG
  18. #pragma code_seg(AFX_CORE_SEG)
  19. #endif
  20.  
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char BASED_CODE THIS_FILE[] = __FILE__;
  24. #define new DEBUG_NEW
  25. #endif
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. // Standard exception processing
  29.  
  30. IMPLEMENT_DYNAMIC(CResourceException, CException)
  31. static  CResourceException NEAR simpleResourceException; 
  32. void AfxThrowResourceException()                            
  33.     { afxExceptionContext.Throw(&simpleResourceException, TRUE); }
  34.  
  35.  
  36. /////////////////////////////////////////////////////////////////////////////
  37. // Diagnostic Output
  38. #ifdef _DEBUG
  39. CDumpContext& operator<<(CDumpContext& dc, SIZE size)
  40. {
  41.     return dc << "(" << size.cx << " x " << size.cy << ")";
  42. }
  43.  
  44. CDumpContext& operator<<(CDumpContext& dc, POINT point)
  45. {
  46.     return dc << "(" << point.x << ", " << point.y << ")";
  47. }
  48.  
  49. CDumpContext& operator<<(CDumpContext& dc, const RECT& rect)
  50. {
  51.     return dc << "(L " << rect.left << ", T " << rect.top << ", R " <<
  52.         rect.right << ", B " << rect.bottom << ")";
  53. }
  54. #endif //_DEBUG
  55.  
  56.  
  57.  
  58. /////////////////////////////////////////////////////////////////////////////
  59. // CDC
  60.  
  61. IMPLEMENT_DYNAMIC(CDC, CObject)
  62.  
  63. // Map from HDC to CDC*
  64. class NEAR CDCHandleMap : public CHandleMap
  65. {
  66. public:
  67.     CObject* NewTempObject(HANDLE h)
  68.                 {
  69.                     // don't add in permanent
  70.                     CDC* p = new CDC();
  71.                     p->m_hDC = (HDC)h;       // set after constructed
  72.                     return p;
  73.                 }
  74.     void DeleteTempObject(CObject* ob)
  75.                 {
  76.                     // destructor doesn't do anything
  77.                     ASSERT(ob->IsKindOf(RUNTIME_CLASS(CDC)));
  78.                     ((CDC*)ob)->m_hDC = NULL;
  79.                     delete ob;
  80.                 }
  81. };
  82. static CDCHandleMap NEAR deviceMap;
  83.  
  84. #ifdef _DEBUG
  85. void CDC::AssertValid() const
  86. {
  87.     CObject::AssertValid();
  88. }
  89.  
  90. void CDC::Dump(CDumpContext& dc) const
  91. {
  92.     CObject::Dump(dc);
  93.     dc << "m_hDC = " << m_hDC;
  94. }
  95. #endif
  96.  
  97. CDC*
  98. CDC::FromHandle(HDC hDC)
  99. {
  100.     return (CDC*)deviceMap.FromHandle(hDC);
  101. }
  102.  
  103. void
  104. CDC::DeleteTempMap()
  105. {
  106.     deviceMap.DeleteTemp();
  107. }
  108.  
  109. BOOL
  110. CDC::Attach(HDC hDC)
  111. {
  112.     ASSERT(m_hDC == NULL);      // only attach once, detach on destroy
  113.     if (hDC == NULL)
  114.         return FALSE;
  115.     deviceMap.SetPermanent(m_hDC = hDC, this);
  116.     return TRUE;
  117. }
  118.  
  119. HDC CDC::Detach()
  120. {
  121.     HDC hDC;
  122.     if ((hDC = m_hDC) != NULL)
  123.         deviceMap.RemovePermanent(m_hDC);
  124.     m_hDC = NULL;
  125.     return hDC;
  126. }
  127.  
  128. BOOL CDC::DeleteDC()
  129. {
  130.     if (m_hDC == NULL)
  131.         return FALSE;
  132.      return ::DeleteDC(Detach());
  133. }
  134.  
  135. CDC::~CDC()
  136. {
  137.     if (m_hDC != NULL)
  138.         ::DeleteDC(Detach());
  139. }
  140.  
  141. /////////////////////////////////////////////////////////////////////////////
  142. // Out-of-line routines
  143.  
  144. CGdiObject*
  145. CDC::SelectGdiObject(HDC hDC, HANDLE h)
  146. {
  147.     return CGdiObject::FromHandle(::SelectObject(hDC, h));
  148. }
  149.  
  150. CPalette*
  151. CDC::SelectPalette(CPalette* pPalette, BOOL bForceBackground)
  152. {
  153.     return (CPalette*) CGdiObject::FromHandle(
  154.         ::SelectPalette(m_hDC, (HPALETTE)pPalette->m_hObject, bForceBackground));
  155. }
  156.  
  157. /////////////////////////////////////////////////////////////////////////////
  158. // Helper DCs
  159.  
  160. IMPLEMENT_DYNAMIC(CClientDC, CDC)
  161. IMPLEMENT_DYNAMIC(CWindowDC, CDC)
  162. IMPLEMENT_DYNAMIC(CPaintDC, CDC)
  163. IMPLEMENT_DYNAMIC(CMetaFileDC, CDC)
  164.  
  165. #ifdef _DEBUG
  166. void CClientDC::AssertValid() const
  167. {
  168.     CDC::AssertValid();
  169.     ASSERT(IsWindow(m_hWnd));
  170. }
  171.  
  172. void CClientDC::Dump(CDumpContext& dc) const
  173. {
  174.     CDC::Dump(dc);
  175.     dc << " m_hWnd = " << (UINT)m_hWnd;
  176. }
  177. #endif
  178.  
  179. CClientDC::CClientDC(CWnd* pWnd)
  180. {
  181.     if (!Attach(::GetDC(m_hWnd = pWnd->GetSafeHwnd())))
  182.         AfxThrowResourceException();
  183. }
  184.  
  185. CClientDC::~CClientDC()
  186. {
  187.     ASSERT(m_hDC != NULL);
  188.     ::ReleaseDC(m_hWnd, Detach());
  189. }
  190.  
  191.  
  192. #ifdef _DEBUG
  193. void CWindowDC::AssertValid() const
  194. {
  195.     CDC::AssertValid();
  196.     ASSERT(::IsWindow(m_hWnd));
  197. }
  198.  
  199. void CWindowDC::Dump(CDumpContext& dc) const
  200. {
  201.     CDC::Dump(dc);
  202.     dc << " m_hWnd = " << (UINT)m_hWnd;
  203. }
  204. #endif
  205.  
  206. CWindowDC::CWindowDC(CWnd* pWnd)
  207. {
  208.     if (!Attach(::GetWindowDC(m_hWnd = pWnd->GetSafeHwnd())))
  209.         AfxThrowResourceException();
  210. }
  211.  
  212. CWindowDC::~CWindowDC()
  213. {
  214.     ASSERT(m_hDC != NULL);
  215.     ::ReleaseDC(m_hWnd, Detach());
  216. }
  217.  
  218. #ifdef _DEBUG
  219. void CPaintDC::AssertValid() const
  220. {
  221.     CDC::AssertValid();
  222.     ASSERT(::IsWindow(m_hWnd));
  223. }
  224.  
  225. void CPaintDC::Dump(CDumpContext& dc) const
  226. {
  227.     CDC::Dump(dc);
  228.     dc << "\nm_hWnd = " << (UINT)m_hWnd;
  229.     dc << "\nm_ps.hdc = " << (UINT)m_ps.hdc;
  230.     dc << "\nm_ps.fErase = " << m_ps.fErase;
  231.     dc << "\nm_ps.rcPaint = " << (CRect)m_ps.rcPaint;
  232. }
  233. #endif
  234.  
  235. CPaintDC::CPaintDC(CWnd* pWnd)
  236. {
  237.     ASSERT_VALID(pWnd);
  238.     if (!Attach(::BeginPaint(m_hWnd = pWnd->m_hWnd, &m_ps)))
  239.         AfxThrowResourceException();
  240. }
  241.  
  242. CPaintDC::~CPaintDC()
  243. {
  244.     ASSERT(m_hDC != NULL);
  245.     ::EndPaint(m_hWnd, &m_ps);
  246.     Detach();
  247. }
  248.  
  249. /////////////////////////////////////////////////////////////////////////////
  250. // CGdiObject
  251.  
  252. IMPLEMENT_DYNAMIC(CGdiObject, CObject)
  253.  
  254. // Map from H??? to CGdiObject*
  255.  
  256. class NEAR CGdiHandleMap : public CHandleMap
  257. {
  258. public:
  259.     CObject* NewTempObject(HANDLE hObject)
  260.                 {
  261.                     // don't add in permanent
  262.                     CGdiObject* p = new CGdiObject;
  263.                     p->m_hObject = hObject;     // set after constructed
  264.                     return p;
  265.                 }
  266.     void DeleteTempObject(CObject* ob)
  267.                 {
  268.                     ASSERT(ob->IsKindOf(RUNTIME_CLASS(CGdiObject)));
  269.                     ((CGdiObject*)ob)->m_hObject = NULL;
  270.                                     // clear before destructed
  271.                     delete ob;
  272.                 }
  273. };
  274. static CGdiHandleMap NEAR gdiMap;
  275.  
  276. #ifdef _DEBUG
  277. void CGdiObject::Dump(CDumpContext& dc) const
  278. {
  279.     CObject::Dump(dc);
  280.     dc << " m_hObject = " << (UINT)m_hObject;
  281. }
  282. #endif
  283.  
  284. CGdiObject* 
  285. CGdiObject::FromHandle(HANDLE h)
  286. {
  287.     return (CGdiObject*)gdiMap.FromHandle(h);
  288. }
  289.  
  290. void
  291. CGdiObject::DeleteTempMap()
  292. {
  293.     gdiMap.DeleteTemp();
  294. }
  295.  
  296. BOOL
  297. CGdiObject::Attach(HANDLE hObject)
  298. {
  299.     ASSERT(m_hObject == NULL);      // only attach once, detach on destroy
  300.     if (hObject == NULL)
  301.         return FALSE;
  302.     gdiMap.SetPermanent(m_hObject = hObject, this);
  303.     return TRUE;
  304. }
  305.  
  306. HANDLE CGdiObject::Detach()
  307. {
  308.     HANDLE hObject;
  309.     if ((hObject = m_hObject) != NULL)
  310.     {
  311.         gdiMap.RemovePermanent(m_hObject);
  312.         // because of stock objects, it may be in temporary map too
  313.         gdiMap.RemoveTemporary(m_hObject);
  314.     }
  315.     m_hObject = NULL;
  316.     return hObject;
  317. }
  318.  
  319. BOOL CGdiObject::DeleteObject()
  320. {
  321.     if (m_hObject == NULL)
  322.         return FALSE;
  323.     return ::DeleteObject(Detach());
  324. }
  325.  
  326. CGdiObject::~CGdiObject()
  327. {
  328.     DeleteObject();
  329. }
  330.  
  331. /////////////////////////////////////////////////////////////////////////////
  332. // Standard GDI objects
  333.  
  334. IMPLEMENT_DYNAMIC(CPen, CGdiObject)
  335. IMPLEMENT_DYNAMIC(CBrush, CGdiObject)
  336. IMPLEMENT_DYNAMIC(CFont, CGdiObject)
  337. IMPLEMENT_DYNAMIC(CBitmap, CGdiObject)
  338. IMPLEMENT_DYNAMIC(CPalette, CGdiObject)
  339. IMPLEMENT_DYNAMIC(CRgn, CGdiObject)
  340.  
  341. /////////////////////////////////////////////////////////////////////////////
  342. // Out-of-line constructors
  343.  
  344. ////////////////////////////////////////////
  345. // CPen
  346.  
  347. CPen::CPen(int nPenStyle, int nWidth, DWORD crColor)
  348. {
  349.     if (!Attach(::CreatePen(nPenStyle, nWidth, crColor)))
  350.         AfxThrowResourceException();
  351. }
  352.  
  353. ////////////////////////////////////////////
  354. // CBrush
  355.  
  356. CBrush::CBrush(DWORD crColor)
  357. {
  358.     if (!Attach(::CreateSolidBrush(crColor)))
  359.         AfxThrowResourceException();
  360. }
  361.  
  362. CBrush::CBrush(int nIndex, DWORD crColor)
  363. {
  364.     if (!Attach(::CreateHatchBrush(nIndex, crColor)))
  365.         AfxThrowResourceException();
  366. }
  367.  
  368. CBrush::CBrush(CBitmap* pBitmap)
  369. {
  370.     if (!Attach(::CreatePatternBrush((HBITMAP)pBitmap->m_hObject)))
  371.         AfxThrowResourceException();
  372. }
  373.  
  374. /////////////////////////////////////////////////////////////////////////////
  375.