home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / MFC / SRC / WINGDI.CP_ / WINGDI.CP
Encoding:
Text File  |  1993-02-08  |  22.9 KB  |  992 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 and/or WinHelp documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11.  
  12. #include "stdafx.h"
  13. #include "winhand_.h"
  14.  
  15. #ifdef AFX_CORE1_SEG
  16. #pragma code_seg(AFX_CORE1_SEG)
  17. #endif
  18.  
  19. #ifdef _DEBUG
  20. #undef THIS_FILE
  21. static char BASED_CODE THIS_FILE[] = __FILE__;
  22. #endif
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25. // Standard exception processing
  26.  
  27. // resource failure
  28. IMPLEMENT_DYNAMIC(CResourceException, CException)
  29. static CResourceException NEAR simpleResourceException;
  30. void AFXAPI AfxThrowResourceException()
  31.     { afxExceptionContext.Throw(&simpleResourceException, TRUE); }
  32.  
  33. // user alert
  34. IMPLEMENT_DYNAMIC(CUserException, CException)
  35. static CUserException NEAR simpleUserException;
  36. void AFXAPI AfxThrowUserException()
  37.     { afxExceptionContext.Throw(&simpleUserException, TRUE); }
  38.  
  39. /////////////////////////////////////////////////////////////////////////////
  40. // Diagnostic Output
  41. #ifdef _DEBUG
  42. CDumpContext& AFXAPI operator<<(CDumpContext& dc, SIZE size)
  43. {
  44.     return dc << "(" << size.cx << " x " << size.cy << ")";
  45. }
  46.  
  47. CDumpContext& AFXAPI operator<<(CDumpContext& dc, POINT point)
  48. {
  49.     return dc << "(" << point.x << ", " << point.y << ")";
  50. }
  51.  
  52. CDumpContext& AFXAPI operator<<(CDumpContext& dc, const RECT& rect)
  53. {
  54.     return dc << "(L " << rect.left << ", T " << rect.top << ", R " <<
  55.         rect.right << ", B " << rect.bottom << ")";
  56. }
  57. #endif //_DEBUG
  58.  
  59.  
  60.  
  61. /////////////////////////////////////////////////////////////////////////////
  62. // CDC
  63.  
  64. IMPLEMENT_DYNCREATE(CDC, CObject)
  65.  
  66. CDC::CDC()
  67. {
  68.     m_hDC = NULL;
  69.     m_hAttribDC = NULL;
  70.     m_bPrinting = FALSE;
  71. }
  72.  
  73. #ifdef _DEBUG
  74. void CDC::AssertValid() const
  75. {
  76.     CObject::AssertValid();
  77. }
  78.  
  79. void CDC::Dump(CDumpContext& dc) const
  80. {
  81.     CObject::Dump(dc);
  82.     AFX_DUMP1(dc, " m_hDC = ", (UINT)m_hDC);
  83.     AFX_DUMP1(dc, "\nm_hAttribDC = ", (UINT)m_hAttribDC);
  84.     AFX_DUMP1(dc, "\nm_bPrinting = ", m_bPrinting);
  85. }
  86. #endif //_DEBUG
  87.  
  88. #ifndef _AFXDLL
  89. static CHandleMap NEAR _afxMapHDC(RUNTIME_CLASS(CDC), 2);
  90. #else
  91. #define _afxMapHDC (*_AfxGetAppData()->appMapHDC)
  92. #endif
  93.  
  94. void PASCAL CDC::DeleteTempMap()
  95. {
  96.     _afxMapHDC.DeleteTemp();
  97. }
  98.  
  99.  
  100. CDC* PASCAL CDC::FromHandle(HDC hDC)
  101. {
  102.     CDC* pDC = (CDC*)_afxMapHDC.FromHandle(hDC);
  103.     ASSERT(pDC == NULL || pDC->m_hDC == hDC);
  104.     return pDC;
  105. }
  106.  
  107. BOOL CDC::Attach(HDC hDC)
  108. {
  109.     ASSERT(m_hDC == NULL);      // only attach once, detach on destroy
  110.     ASSERT(m_hAttribDC == NULL);    // only attach to an empty DC
  111.  
  112.     if (hDC == NULL)
  113.         return FALSE;
  114.     _afxMapHDC.SetPermanent(m_hDC = hDC, this);
  115.  
  116.     SetAttribDC(m_hDC);     // Default to same as output
  117.     return TRUE;
  118. }
  119.  
  120. HDC CDC::Detach()
  121. {
  122.     HDC hDC;
  123.     if ((hDC = m_hDC) != NULL)
  124.         _afxMapHDC.RemoveHandle(m_hDC);
  125.  
  126.     ReleaseAttribDC();
  127.     m_hDC = NULL;
  128.     return hDC;
  129. }
  130.  
  131. BOOL CDC::DeleteDC()
  132. {
  133.     if (m_hDC == NULL)
  134.         return FALSE;
  135.  
  136.     return ::DeleteDC(Detach());
  137. }
  138.  
  139. CDC::~CDC()
  140. {
  141.     if (m_hDC != NULL)
  142.         ::DeleteDC(Detach());
  143. }
  144.  
  145.  
  146. void CDC::SetAttribDC(HDC hDC)  // Set the Attribute DC
  147. {
  148.     m_hAttribDC = hDC;
  149. }
  150.  
  151. void CDC::SetOutputDC(HDC hDC)  // Set the Output DC
  152. {
  153. #ifdef _DEBUG
  154.     CObject* pObject;
  155.     if (_afxMapHDC.LookupPermanent(m_hDC, pObject) && pObject == this)
  156.     {
  157.         TRACE0("Cannot Set Output hDC on Attached CDC\n");
  158.         ASSERT(FALSE);
  159.     }
  160. #endif
  161.     m_hDC = hDC;
  162. }
  163.  
  164. void CDC::ReleaseAttribDC()     // Release the Attribute DC
  165. {
  166.     m_hAttribDC = NULL;
  167. }
  168.  
  169. void CDC::ReleaseOutputDC()     // Release the Output DC
  170. {
  171. #ifdef _DEBUG
  172.     CObject* pObject;
  173.     if (_afxMapHDC.LookupPermanent(m_hDC, pObject) && pObject == this)
  174.     {
  175.         TRACE0("Cannot Release Output hDC on Attached CDC\n");
  176.         ASSERT(FALSE);
  177.     }
  178. #endif
  179.     m_hDC = NULL;
  180. }
  181.  
  182. // Win 3.0 and 3.1 compatible printing routines
  183.  
  184. int CDC::StartDoc(LPCSTR lpszDocName)
  185. {
  186.     DOCINFO di;
  187.     di.cbSize = sizeof(DOCINFO);
  188.     di.lpszDocName = lpszDocName;
  189.     di.lpszOutput = NULL;
  190.     return StartDoc(&di);
  191. }
  192.  
  193. int CDC::StartDoc(LPDOCINFO lpDocInfo)
  194. {
  195.     if (!afxData.bWin31)
  196.     {
  197.         // Output to file not supported in Win3.0
  198.         ASSERT(lpDocInfo->lpszOutput == NULL);
  199.         ASSERT(lstrlen(lpDocInfo->lpszDocName) < 32);
  200.         return Escape(STARTDOC, lstrlen(lpDocInfo->lpszDocName),
  201.              lpDocInfo->lpszDocName, NULL);
  202.     }
  203.     else
  204.     {
  205.         return ::StartDoc(m_hDC, lpDocInfo);
  206.     }
  207. }
  208.  
  209. int CDC::StartPage()
  210. {
  211.     if (!afxData.bWin31)
  212.         return TRUE;
  213.     else
  214.         return ::StartPage(m_hDC);
  215. }
  216.  
  217. int CDC::EndPage()
  218. {
  219.     if (!afxData.bWin31)
  220.         return ::Escape(m_hDC, NEWFRAME, 0, NULL, NULL);
  221.     else
  222.         return ::EndPage(m_hDC);
  223. }
  224.  
  225. int CDC::SetAbortProc(BOOL (CALLBACK EXPORT* lpfn)(HDC, int))
  226. {
  227.     if (!afxData.bWin31)
  228.         return ::Escape(m_hDC, SETABORTPROC, 0, (LPCSTR)lpfn, NULL);
  229.     else
  230.         return ::SetAbortProc(m_hDC, (ABORTPROC)lpfn);
  231. }
  232.  
  233. int CDC::AbortDoc()
  234. {
  235.     if (!afxData.bWin31)
  236.         return ::Escape(m_hDC, ABORTDOC, 0, NULL, NULL);
  237.     else
  238.         return ::AbortDoc(m_hDC);
  239. }
  240.  
  241. int CDC::EndDoc()
  242. {
  243.     if (!afxData.bWin31)
  244.         return ::Escape(m_hDC, ENDDOC, 0, NULL, NULL);
  245.     else
  246.         return ::EndDoc(m_hDC);
  247. }
  248.  
  249. /////////////////////////////////////////////////////////////////////////////
  250. // Out-of-line routines
  251.  
  252. int CDC::SaveDC()
  253. {
  254.     ASSERT(m_hDC != NULL);
  255.     int nRetVal;
  256.     if (m_hAttribDC != NULL)
  257.         nRetVal = ::SaveDC(m_hAttribDC);
  258.     if (m_hDC != m_hAttribDC && ::SaveDC(m_hDC) != 0)
  259.         nRetVal = -1;   // -1 is the only valid restore value for complex DCs
  260.     return nRetVal;
  261. }
  262.  
  263. BOOL CDC::RestoreDC(int nSavedDC)
  264. {
  265.     // if two distinct DCs, nSavedDC can only be -1
  266.     ASSERT(m_hDC != NULL);
  267.     ASSERT(m_hDC == m_hAttribDC || nSavedDC == -1);
  268.  
  269.     BOOL bRetVal = TRUE;
  270.     if (m_hDC != m_hAttribDC)
  271.         bRetVal = ::RestoreDC(m_hDC, nSavedDC);
  272.     if (m_hAttribDC != NULL)
  273.         bRetVal = (bRetVal && ::RestoreDC(m_hAttribDC, nSavedDC));
  274.     return bRetVal;
  275. }
  276.  
  277. CGdiObject* PASCAL CDC::SelectGdiObject(HDC hDC, HGDIOBJ h)
  278. {
  279.     return CGdiObject::FromHandle(::SelectObject(hDC, h));
  280. }
  281.  
  282. CGdiObject* CDC::SelectStockObject(int nIndex)
  283. {
  284.     ASSERT(m_hDC != NULL);
  285.  
  286.     HGDIOBJ hObject = ::GetStockObject(nIndex);
  287.     HGDIOBJ hOldObj;
  288.  
  289.     ASSERT(hObject != NULL);
  290.     if (m_hDC != m_hAttribDC)
  291.         hOldObj = ::SelectObject(m_hDC, hObject);
  292.     if (m_hAttribDC != NULL)
  293.         hOldObj = ::SelectObject(m_hAttribDC, hObject);
  294.     return CGdiObject::FromHandle(hOldObj);
  295. }
  296.  
  297. CPen* CDC::SelectObject(CPen* pPen)
  298. {
  299.     ASSERT(m_hDC != NULL);
  300.     HGDIOBJ hOldObj;
  301.     if (m_hDC != m_hAttribDC)
  302.         hOldObj = ::SelectObject(m_hDC, pPen->GetSafeHandle());
  303.     if (m_hAttribDC != NULL)
  304.         hOldObj = ::SelectObject(m_hAttribDC, pPen->GetSafeHandle());
  305.     return (CPen*)CGdiObject::FromHandle(hOldObj);
  306. }
  307.  
  308. CBrush* CDC::SelectObject(CBrush* pBrush)
  309. {
  310.     ASSERT(m_hDC != NULL);
  311.     HGDIOBJ hOldObj;
  312.     if (m_hDC != m_hAttribDC)
  313.         hOldObj = ::SelectObject(m_hDC, pBrush->GetSafeHandle());
  314.     if (m_hAttribDC != NULL)
  315.         hOldObj = ::SelectObject(m_hAttribDC, pBrush->GetSafeHandle());
  316.     return (CBrush*)CGdiObject::FromHandle(hOldObj);
  317. }
  318.  
  319. CFont* CDC::SelectObject(CFont* pFont)
  320. {
  321.     ASSERT(m_hDC != NULL);
  322.     HGDIOBJ hOldObj;
  323.     if (m_hDC != m_hAttribDC)
  324.         hOldObj = ::SelectObject(m_hDC, pFont->GetSafeHandle());
  325.     if (m_hAttribDC != NULL)
  326.         hOldObj = ::SelectObject(m_hAttribDC, pFont->GetSafeHandle());
  327.     return (CFont*)CGdiObject::FromHandle(hOldObj);
  328. }
  329.  
  330. int CDC::SelectObject(CRgn* pRgn)
  331. {
  332.     ASSERT(m_hDC != NULL);
  333.     int nRetVal;
  334.     if (m_hDC != m_hAttribDC)
  335.         nRetVal = (int)::SelectObject(m_hDC, pRgn->GetSafeHandle());
  336.     if (m_hAttribDC != NULL)
  337.         nRetVal = (int)::SelectObject(m_hAttribDC, pRgn->GetSafeHandle());
  338.     return nRetVal;
  339. }
  340.  
  341. CPalette* CDC::SelectPalette(CPalette* pPalette, BOOL bForceBackground)
  342. {
  343.     ASSERT(m_hDC != NULL);
  344.  
  345.     return (CPalette*) CGdiObject::FromHandle(::SelectPalette(m_hDC,
  346.         (HPALETTE)pPalette->GetSafeHandle(), bForceBackground));
  347. }
  348.  
  349. COLORREF CDC::SetBkColor(COLORREF crColor)
  350. {
  351.     ASSERT(m_hDC != NULL);
  352.     COLORREF crRetVal;
  353.     if (m_hDC != m_hAttribDC)
  354.         crRetVal = ::SetBkColor(m_hDC, crColor);
  355.     if (m_hAttribDC != NULL)
  356.         crRetVal = ::SetBkColor(m_hAttribDC, crColor);
  357.     return crRetVal;
  358. }
  359.  
  360. int CDC::SetBkMode(int nBkMode)
  361. {
  362.     ASSERT(m_hDC != NULL);
  363.     int nRetVal;
  364.     if (m_hDC != m_hAttribDC)
  365.         nRetVal = ::SetBkMode(m_hDC, nBkMode);
  366.     if (m_hAttribDC != NULL)
  367.         nRetVal = ::SetBkMode(m_hAttribDC, nBkMode);
  368.     return nRetVal;
  369. }
  370.  
  371. int CDC::SetPolyFillMode(int nPolyFillMode)
  372. {
  373.     ASSERT(m_hDC != NULL);
  374.     int nRetVal;
  375.     if (m_hDC != m_hAttribDC)
  376.         nRetVal = ::SetPolyFillMode(m_hDC, nPolyFillMode);
  377.     if (m_hAttribDC != NULL)
  378.         nRetVal = ::SetPolyFillMode(m_hAttribDC, nPolyFillMode);
  379.     return nRetVal;
  380. }
  381.  
  382. int CDC::SetROP2(int nDrawMode)
  383. {
  384.     ASSERT(m_hDC != NULL);
  385.     int nRetVal;
  386.     if (m_hDC != m_hAttribDC)
  387.         nRetVal = ::SetROP2(m_hDC, nDrawMode);
  388.     if (m_hAttribDC != NULL)
  389.         nRetVal = ::SetROP2(m_hAttribDC, nDrawMode);
  390.     return nRetVal;
  391. }
  392.  
  393. int CDC::SetStretchBltMode(int nStretchMode)
  394. {
  395.     ASSERT(m_hDC != NULL);
  396.     int nRetVal;
  397.     if (m_hDC != m_hAttribDC)
  398.         nRetVal = ::SetStretchBltMode(m_hDC, nStretchMode);
  399.     if (m_hAttribDC != NULL)
  400.         nRetVal = ::SetStretchBltMode(m_hAttribDC, nStretchMode);
  401.     return nRetVal;
  402. }
  403.  
  404. COLORREF CDC::SetTextColor(COLORREF crColor)
  405. {
  406.     ASSERT(m_hDC != NULL);
  407.     COLORREF crRetVal;
  408.     if (m_hDC != m_hAttribDC)
  409.         crRetVal = ::SetTextColor(m_hDC, crColor);
  410.     if (m_hAttribDC != NULL)
  411.         crRetVal = ::SetTextColor(m_hAttribDC, crColor);
  412.     return crRetVal;
  413. }
  414.  
  415. int CDC::SetMapMode(int nMapMode)
  416. {
  417.     ASSERT(m_hDC != NULL);
  418.     int nRetVal;
  419.     if (m_hDC != m_hAttribDC)
  420.         nRetVal = ::SetMapMode(m_hDC, nMapMode);
  421.     if (m_hAttribDC != NULL)
  422.         nRetVal = ::SetMapMode(m_hAttribDC, nMapMode);
  423.     return nRetVal;
  424. }
  425.  
  426. CPoint CDC::SetViewportOrg(int x, int y)
  427. {
  428.     ASSERT(m_hDC != NULL);
  429.     CPoint point;
  430.     if (m_hDC != m_hAttribDC)
  431.         point = ::SetViewportOrg(m_hDC, x, y);
  432.     if (m_hAttribDC != NULL)
  433.         point = ::SetViewportOrg(m_hAttribDC, x, y);
  434.     return point;
  435. }
  436.  
  437. CPoint CDC::OffsetViewportOrg(int nWidth, int nHeight)
  438. {
  439.     ASSERT(m_hDC != NULL);
  440.     CPoint point;
  441.     if (m_hDC != m_hAttribDC)
  442.         point = ::OffsetViewportOrg(m_hDC, nWidth, nHeight);
  443.     if (m_hAttribDC != NULL)
  444.         point = ::OffsetViewportOrg(m_hAttribDC, nWidth, nHeight);
  445.     return point;
  446. }
  447.  
  448. CSize CDC::SetViewportExt(int x, int y)
  449. {
  450.     ASSERT(m_hDC != NULL);
  451.     CSize size;
  452.     if (m_hDC != m_hAttribDC)
  453.         size = ::SetViewportExt(m_hDC, x, y);
  454.     if (m_hAttribDC != NULL)
  455.         size = ::SetViewportExt(m_hAttribDC, x, y);
  456.     return size;
  457. }
  458.  
  459. CSize CDC::ScaleViewportExt(int xNum, int xDenom, int yNum, int yDenom)
  460. {
  461.     ASSERT(m_hDC != NULL);
  462.     CSize size;
  463.     if (m_hDC != m_hAttribDC)
  464.         size = ::ScaleViewportExt(m_hDC, xNum, xDenom, yNum, yDenom);
  465.     if (m_hAttribDC != NULL)
  466.         size = ::ScaleViewportExt(m_hAttribDC, xNum, xDenom, yNum, yDenom);
  467.     return size;
  468. }
  469.  
  470. CPoint CDC::SetWindowOrg(int x, int y)
  471. {
  472.     ASSERT(m_hDC != NULL);
  473.     CPoint point;
  474.     if (m_hDC != m_hAttribDC)
  475.         point = ::SetWindowOrg(m_hDC, x, y);
  476.     if (m_hAttribDC != NULL)
  477.         point = ::SetWindowOrg(m_hAttribDC, x, y);
  478.     return point;
  479. }
  480.  
  481. CPoint CDC::OffsetWindowOrg(int nWidth, int nHeight)
  482. {
  483.     ASSERT(m_hDC != NULL);
  484.     CPoint point;
  485.     if (m_hDC != m_hAttribDC)
  486.         point = ::OffsetWindowOrg(m_hDC, nWidth, nHeight);
  487.     if (m_hAttribDC != NULL)
  488.         point = ::OffsetWindowOrg(m_hAttribDC, nWidth, nHeight);
  489.     return point;
  490. }
  491.  
  492. CSize CDC::ScaleWindowExt(int xNum, int xDenom, int yNum, int yDenom)
  493. {
  494.     ASSERT(m_hDC != NULL);
  495.     CSize size;
  496.     if (m_hDC != m_hAttribDC)
  497.         size = ::ScaleWindowExt(m_hDC, xNum, xDenom, yNum, yDenom);
  498.     if (m_hAttribDC != NULL)
  499.         size = ::ScaleWindowExt(m_hAttribDC, xNum, xDenom, yNum, yDenom);
  500.     return size;
  501. }
  502.  
  503. CSize CDC::SetWindowExt(int x, int y)
  504. {
  505.     ASSERT(m_hDC != NULL);
  506.     CSize size;
  507.     if (m_hDC != m_hAttribDC)
  508.         size = ::SetWindowExt(m_hDC, x, y);
  509.     if (m_hAttribDC != NULL)
  510.         size = ::SetWindowExt(m_hAttribDC, x, y);
  511.     return size;
  512. }
  513.  
  514.  
  515. int CDC::GetClipBox(LPRECT lpRect) const
  516. {
  517.     ASSERT(m_hDC != NULL);
  518.     return ::GetClipBox(m_hDC, lpRect);
  519. }
  520.  
  521. int CDC::SelectClipRgn(CRgn* pRgn)
  522. {
  523.     ASSERT(m_hDC != NULL);
  524.     int nRetVal;
  525.     if (m_hDC != m_hAttribDC)
  526.         nRetVal = ::SelectClipRgn(m_hDC, (HRGN)pRgn->GetSafeHandle());
  527.     if (m_hAttribDC != NULL)
  528.         nRetVal = ::SelectClipRgn(m_hAttribDC, (HRGN)pRgn->GetSafeHandle());
  529.     return nRetVal;
  530. }
  531.  
  532. int CDC::ExcludeClipRect(int x1, int y1, int x2, int y2)
  533. {
  534.     ASSERT(m_hDC != NULL);
  535.     int nRetVal;
  536.     if (m_hDC != m_hAttribDC)
  537.         nRetVal = ::ExcludeClipRect(m_hDC, x1, y1, x2, y2);
  538.     if (m_hAttribDC != NULL)
  539.         nRetVal = ::ExcludeClipRect(m_hAttribDC, x1, y1, x2, y2);
  540.     return nRetVal;
  541. }
  542.  
  543. int CDC::ExcludeClipRect(LPCRECT lpRect)
  544. {
  545.     ASSERT(m_hDC != NULL);
  546.     int nRetVal;
  547.     if (m_hDC != m_hAttribDC)
  548.         nRetVal = ::ExcludeClipRect(m_hDC, lpRect->left, lpRect->top,
  549.             lpRect->right, lpRect->bottom);
  550.     if (m_hAttribDC != NULL)
  551.         nRetVal = ::ExcludeClipRect(m_hAttribDC, lpRect->left, lpRect->top,
  552.             lpRect->right, lpRect->bottom);
  553.     return nRetVal;
  554. }
  555.  
  556. int CDC::IntersectClipRect(int x1, int y1, int x2, int y2)
  557. {
  558.     ASSERT(m_hDC != NULL);
  559.     int nRetVal;
  560.     if (m_hDC != m_hAttribDC)
  561.         nRetVal = ::IntersectClipRect(m_hDC, x1, y1, x2, y2);
  562.     if (m_hAttribDC != NULL)
  563.         nRetVal = ::IntersectClipRect(m_hAttribDC, x1, y1, x2, y2);
  564.     return nRetVal;
  565. }
  566.  
  567. int CDC::IntersectClipRect(LPCRECT lpRect)
  568. {
  569.     ASSERT(m_hDC != NULL);
  570.     int nRetVal;
  571.     if (m_hDC != m_hAttribDC)
  572.         nRetVal = ::IntersectClipRect(m_hDC, lpRect->left, lpRect->top,
  573.             lpRect->right, lpRect->bottom);
  574.     if (m_hAttribDC != NULL)
  575.         nRetVal = ::IntersectClipRect(m_hAttribDC, lpRect->left, lpRect->top,
  576.             lpRect->right, lpRect->bottom);
  577.     return nRetVal;
  578. }
  579.  
  580. int CDC::OffsetClipRgn(int x, int y)
  581. {
  582.     ASSERT(m_hDC != NULL);
  583.     int nRetVal;
  584.     if (m_hDC != m_hAttribDC)
  585.         nRetVal = ::OffsetClipRgn(m_hDC, x, y);
  586.     if (m_hAttribDC != NULL)
  587.         nRetVal = ::OffsetClipRgn(m_hAttribDC, x, y);
  588.     return nRetVal;
  589. }
  590.  
  591. int CDC::OffsetClipRgn(SIZE size)
  592. {
  593.     ASSERT(m_hDC != NULL);
  594.     int nRetVal;
  595.     if (m_hDC != m_hAttribDC)
  596.         nRetVal = ::OffsetClipRgn(m_hDC, size.cx, size.cy);
  597.     if (m_hAttribDC != NULL)
  598.         nRetVal = ::OffsetClipRgn(m_hAttribDC, size.cx, size.cy);
  599.     return nRetVal;
  600. }
  601.  
  602.  
  603. CPoint CDC::MoveTo(int x, int y)
  604. {
  605.     ASSERT(m_hDC != NULL);
  606.     CPoint point;
  607.     if (m_hDC != m_hAttribDC)
  608.         point = ::MoveTo(m_hDC, x, y);
  609.     if (m_hAttribDC != NULL)
  610.         point = ::MoveTo(m_hAttribDC, x, y);
  611.     return point;
  612. }
  613.  
  614.  
  615. BOOL CDC::LineTo(int x, int y)
  616. {
  617.     ASSERT(m_hDC != NULL);
  618.     if (m_hAttribDC != NULL && m_hDC != m_hAttribDC)
  619.         ::MoveTo(m_hAttribDC, x, y);
  620.     return ::LineTo(m_hDC, x, y);
  621. }
  622.  
  623. UINT CDC::SetTextAlign(UINT nFlags)
  624. {
  625.     ASSERT(m_hDC != NULL);
  626.     UINT nRetVal;
  627.     if (m_hDC != m_hAttribDC)
  628.         ::SetTextAlign(m_hDC, nFlags);
  629.     if (m_hAttribDC != NULL)
  630.         nRetVal = ::SetTextAlign(m_hAttribDC, nFlags);
  631.     return nRetVal;
  632. }
  633.  
  634. int CDC::SetTextJustification(int nBreakExtra, int nBreakCount)
  635. {
  636.     ASSERT(m_hDC != NULL);
  637.     int nRetVal;
  638.     if (m_hDC != m_hAttribDC)
  639.         nRetVal = ::SetTextJustification(m_hDC, nBreakExtra, nBreakCount);
  640.     if (m_hAttribDC != NULL)
  641.         nRetVal = ::SetTextJustification(m_hAttribDC, nBreakExtra, nBreakCount);
  642.     return nRetVal;
  643. }
  644.  
  645. int CDC::SetTextCharacterExtra(int nCharExtra)
  646. {
  647.     ASSERT(m_hDC != NULL);
  648.     int nRetVal;
  649.     if (m_hDC != m_hAttribDC)
  650.         nRetVal = ::SetTextCharacterExtra(m_hDC, nCharExtra);
  651.     if (m_hAttribDC != NULL)
  652.         nRetVal = ::SetTextCharacterExtra(m_hAttribDC, nCharExtra);
  653.     return nRetVal;
  654. }
  655.  
  656. DWORD CDC::SetMapperFlags(DWORD dwFlag)
  657. {
  658.     ASSERT(m_hDC != NULL);
  659.     DWORD dwRetVal;
  660.     if (m_hDC != m_hAttribDC)
  661.         dwRetVal = ::SetMapperFlags(m_hDC, dwFlag);
  662.     if (m_hAttribDC != NULL)
  663.         dwRetVal = ::SetMapperFlags(m_hAttribDC, dwFlag);
  664.     return dwRetVal;
  665. }
  666.  
  667. /////////////////////////////////////////////////////////////////////////////
  668. // Helper DCs
  669.  
  670. IMPLEMENT_DYNAMIC(CClientDC, CDC)
  671. IMPLEMENT_DYNAMIC(CWindowDC, CDC)
  672. IMPLEMENT_DYNAMIC(CPaintDC, CDC)
  673.  
  674. #ifdef _DEBUG
  675. void CClientDC::AssertValid() const
  676. {
  677.     CDC::AssertValid();
  678.     ASSERT(::IsWindow(m_hWnd));
  679. }
  680.  
  681. void CClientDC::Dump(CDumpContext& dc) const
  682. {
  683.     CDC::Dump(dc);
  684.     AFX_DUMP1(dc, "\nm_hWnd = ", (UINT)m_hWnd);
  685. }
  686. #endif
  687.  
  688. CClientDC::CClientDC(CWnd* pWnd)
  689. {
  690.     if (!Attach(::GetDC(m_hWnd = pWnd->GetSafeHwnd())))
  691.         AfxThrowResourceException();
  692. }
  693.  
  694. CClientDC::~CClientDC()
  695. {
  696.     ASSERT(m_hDC != NULL);
  697.     ::ReleaseDC(m_hWnd, Detach());
  698. }
  699.  
  700.  
  701. #ifdef _DEBUG
  702. void CWindowDC::AssertValid() const
  703. {
  704.     CDC::AssertValid();
  705.     ASSERT(::IsWindow(m_hWnd));
  706. }
  707.  
  708. void CWindowDC::Dump(CDumpContext& dc) const
  709. {
  710.     CDC::Dump(dc);
  711.     AFX_DUMP1(dc, "\nm_hWnd = ", (UINT)m_hWnd);
  712. }
  713. #endif
  714.  
  715. CWindowDC::CWindowDC(CWnd* pWnd)
  716. {
  717.     if (!Attach(::GetWindowDC(m_hWnd = pWnd->GetSafeHwnd())))
  718.         AfxThrowResourceException();
  719. }
  720.  
  721. CWindowDC::~CWindowDC()
  722. {
  723.     ASSERT(m_hDC != NULL);
  724.     ::ReleaseDC(m_hWnd, Detach());
  725. }
  726.  
  727. #ifdef _DEBUG
  728. void CPaintDC::AssertValid() const
  729. {
  730.     CDC::AssertValid();
  731.     ASSERT(::IsWindow(m_hWnd));
  732. }
  733.  
  734. void CPaintDC::Dump(CDumpContext& dc) const
  735. {
  736.     CDC::Dump(dc);
  737.     AFX_DUMP1(dc, "\nm_hWnd = ", (UINT)m_hWnd);
  738.     AFX_DUMP1(dc, "\nm_ps.hdc = ", (UINT)m_ps.hdc);
  739.     AFX_DUMP1(dc, "\nm_ps.fErase = ", m_ps.fErase);
  740.     AFX_DUMP1(dc, "\nm_ps.rcPaint = ", (CRect)m_ps.rcPaint);
  741. }
  742. #endif
  743.  
  744. CPaintDC::CPaintDC(CWnd* pWnd)
  745. {
  746.     ASSERT_VALID(pWnd);
  747.  
  748.     if (!Attach(::BeginPaint(m_hWnd = pWnd->m_hWnd, &m_ps)))
  749.         AfxThrowResourceException();
  750. }
  751.  
  752. CPaintDC::~CPaintDC()
  753. {
  754.     ASSERT(m_hDC != NULL);
  755.     ::EndPaint(m_hWnd, &m_ps);
  756.     Detach();
  757. }
  758.  
  759. /////////////////////////////////////////////////////////////////////////////
  760. // CGdiObject
  761.  
  762. IMPLEMENT_DYNCREATE(CGdiObject, CObject)
  763.  
  764. #ifdef _DEBUG
  765. void CGdiObject::Dump(CDumpContext& dc) const
  766. {
  767.     CObject::Dump(dc);
  768.     AFX_DUMP1(dc, " m_hObject = ", (UINT)m_hObject);
  769. }
  770.  
  771. void CGdiObject::AssertValid() const
  772. {
  773.     CObject::AssertValid();
  774.     if (afxData.bWin31)
  775.     {
  776.         ASSERT(m_hObject == NULL || ::IsGDIObject(m_hObject));
  777.     }
  778. }
  779. #endif
  780.  
  781. #ifndef _AFXDLL
  782. static CHandleMap NEAR _afxMapHGDIOBJ(RUNTIME_CLASS(CGdiObject));
  783. #else
  784. #define _afxMapHGDIOBJ (*_AfxGetAppData()->appMapHGDIOBJ)
  785. #endif
  786.  
  787. void PASCAL CGdiObject::DeleteTempMap()
  788. {
  789.     _afxMapHGDIOBJ.DeleteTemp();
  790. }
  791.  
  792.  
  793. CGdiObject* PASCAL CGdiObject::FromHandle(HGDIOBJ h)
  794. {
  795.     CGdiObject* pObject = (CGdiObject*)_afxMapHGDIOBJ.FromHandle(h);
  796.     ASSERT(pObject == NULL || pObject->m_hObject == h);
  797.     return pObject;
  798. }
  799.  
  800. BOOL CGdiObject::Attach(HGDIOBJ hObject)
  801. {
  802.     ASSERT(m_hObject == NULL);      // only attach once, detach on destroy
  803.     if (hObject == NULL)
  804.         return FALSE;
  805.     _afxMapHGDIOBJ.SetPermanent(m_hObject = hObject, this);
  806.     return TRUE;
  807. }
  808.  
  809. HGDIOBJ CGdiObject::Detach()
  810. {
  811.     HGDIOBJ hObject;
  812.     if ((hObject = m_hObject) != NULL)
  813.         _afxMapHGDIOBJ.RemoveHandle(m_hObject);
  814.     m_hObject = NULL;
  815.     return hObject;
  816. }
  817.  
  818. BOOL CGdiObject::DeleteObject()
  819. {
  820.     if (m_hObject == NULL)
  821.         return FALSE;
  822.     return ::DeleteObject(Detach());
  823. }
  824.  
  825. CGdiObject::~CGdiObject()
  826. {
  827.     DeleteObject();
  828. }
  829.  
  830. /////////////////////////////////////////////////////////////////////////////
  831. // Standard GDI objects
  832.  
  833. IMPLEMENT_DYNAMIC(CPen, CGdiObject)
  834. IMPLEMENT_DYNAMIC(CBrush, CGdiObject)
  835. IMPLEMENT_DYNAMIC(CFont, CGdiObject)
  836. IMPLEMENT_DYNAMIC(CBitmap, CGdiObject)
  837. IMPLEMENT_DYNAMIC(CPalette, CGdiObject)
  838. IMPLEMENT_DYNAMIC(CRgn, CGdiObject)
  839.  
  840. /////////////////////////////////////////////////////////////////////////////
  841. // Out-of-line constructors
  842.  
  843. ////////////////////////////////////////////
  844. // CPen
  845.  
  846. CPen::CPen(int nPenStyle, int nWidth, COLORREF crColor)
  847. {
  848.     if (!Attach(::CreatePen(nPenStyle, nWidth, crColor)))
  849.         AfxThrowResourceException();
  850. }
  851.  
  852. #ifdef _DEBUG
  853. void CPen::Dump(CDumpContext& dc) const
  854. {
  855.     LOGPEN lp;
  856.  
  857.     CGdiObject::Dump(dc);
  858.  
  859.     if (m_hObject == NULL)
  860.         return;
  861.  
  862.     if (afxData.bWin31 && !::IsGDIObject(m_hObject))
  863.     {
  864.         // not a valid object
  865.         AFX_DUMP0(dc, "  ILLEGAL HPEN");
  866.         return; // don't do anything more
  867.     }
  868.  
  869.     VERIFY(GetObject(sizeof(lp), &lp));
  870.  
  871.     AFX_DUMP1(dc, "\nlgpn.lopnStyle = ", lp.lopnStyle);
  872.     AFX_DUMP1(dc, "\nlgpn.lopnWidth.x (width) = ", lp.lopnWidth.x);
  873.     AFX_DUMP1(dc, "\nlgpn.lopnColor = ", (void FAR*)lp.lopnColor);
  874. }
  875. #endif
  876. ////////////////////////////////////////////
  877. // CBrush
  878.  
  879. CBrush::CBrush(COLORREF crColor)
  880. {
  881.     if (!Attach(::CreateSolidBrush(crColor)))
  882.         AfxThrowResourceException();
  883. }
  884.  
  885. CBrush::CBrush(int nIndex, COLORREF crColor)
  886. {
  887.     if (!Attach(::CreateHatchBrush(nIndex, crColor)))
  888.         AfxThrowResourceException();
  889. }
  890.  
  891. CBrush::CBrush(CBitmap* pBitmap)
  892. {
  893.     ASSERT_VALID(pBitmap);
  894.  
  895.     if (!Attach(::CreatePatternBrush((HBITMAP)pBitmap->m_hObject)))
  896.         AfxThrowResourceException();
  897. }
  898.  
  899. #ifdef _DEBUG
  900. void CBrush::Dump(CDumpContext& dc) const
  901. {
  902.     LOGBRUSH lb;
  903.  
  904.     CGdiObject::Dump(dc);
  905.  
  906.     if (m_hObject == NULL)
  907.         return;
  908.  
  909.     if (afxData.bWin31 && !::IsGDIObject(m_hObject))
  910.     {
  911.         // not a valid window
  912.         AFX_DUMP0(dc, "  ILLEGAL HBRUSH");
  913.         return; // don't do anything more
  914.     }
  915.  
  916.     VERIFY(GetObject(sizeof(lb), &lb));
  917.  
  918.     AFX_DUMP1(dc, "\nlb.lbStyle = ", lb.lbStyle);
  919.     AFX_DUMP1(dc, "\nlb.lbHatch = ", lb.lbHatch);
  920.     AFX_DUMP1(dc, "\nlb.lbColor = ", (void FAR*)lb.lbColor);
  921. }
  922. #endif
  923.  
  924. /////////////////////////////////////////////////////////////////////////////
  925. #ifdef _DEBUG
  926. void CFont::Dump(CDumpContext& dc) const
  927. {
  928.     LOGFONT lf;
  929.  
  930.     CGdiObject::Dump(dc);
  931.  
  932.     if (m_hObject == NULL)
  933.         return;
  934.  
  935.     if (afxData.bWin31 && !::IsGDIObject(m_hObject))
  936.     {
  937.         // not a valid GDI object
  938.         AFX_DUMP0(dc, "  ILLEGAL HFONT");
  939.         return; // don't do anything more
  940.     }
  941.  
  942.     VERIFY(GetObject(sizeof(lf), &lf));
  943.  
  944.     AFX_DUMP1(dc, "\nlf.lfHeight = ", lf.lfHeight);
  945.     AFX_DUMP1(dc, "\nlf.lfWidth = ", lf.lfWidth);
  946.     AFX_DUMP1(dc, "\nlf.lfEscapement = ", lf.lfEscapement);
  947.     AFX_DUMP1(dc, "\nlf.lfOrientation = ", lf.lfOrientation);
  948.     AFX_DUMP1(dc, "\nlf.lfWeight = ", lf.lfWeight);
  949.     AFX_DUMP1(dc, "\nlf.lfItalic = ", (int)lf.lfItalic);
  950.     AFX_DUMP1(dc, "\nlf.lfUnderline = ", (int)lf.lfUnderline);
  951.     AFX_DUMP1(dc, "\nlf.lfStrikeOut = ", (int)lf.lfStrikeOut);
  952.     AFX_DUMP1(dc, "\nlf.lfCharSet = ", (int)lf.lfCharSet);
  953.     AFX_DUMP1(dc, "\nlf.lfOutPrecision = ", (int)lf.lfOutPrecision);
  954.     AFX_DUMP1(dc, "\nlf.lfClipPrecision = ", (int)lf.lfClipPrecision);
  955.     AFX_DUMP1(dc, "\nlf.lfQuality = ", (int)lf.lfQuality);
  956.     AFX_DUMP1(dc, "\nlf.lfPitchAndFamily = ", (int)lf.lfPitchAndFamily);
  957.     AFX_DUMP1(dc, "\nlf.lfFaceName = ", (char*)lf.lfFaceName);
  958. }
  959. #endif
  960.  
  961. /////////////////////////////////////////////////////////////////////////////
  962.  
  963. #ifdef _DEBUG
  964. void CBitmap::Dump(CDumpContext& dc) const
  965. {
  966.     BITMAP bm;
  967.  
  968.     CGdiObject::Dump(dc);
  969.  
  970.     if (m_hObject == NULL)
  971.         return;
  972.  
  973.     if (afxData.bWin31 && !::IsGDIObject(m_hObject))
  974.     {
  975.         // not a valid object
  976.         AFX_DUMP0(dc, "  ILLEGAL HBITMAP");
  977.         return; // don't do anything more
  978.     }
  979.  
  980.     VERIFY(GetObject(sizeof(bm), &bm));
  981.  
  982.     AFX_DUMP1(dc, "\nbm.bmType = ", bm.bmType);
  983.     AFX_DUMP1(dc, "\nbm.bmHeight = ", bm.bmHeight);
  984.     AFX_DUMP1(dc, "\nbm.bmWidth = ", bm.bmWidth);
  985.     AFX_DUMP1(dc, "\nbm.bmWidthBytes = ", bm.bmWidthBytes);
  986.     AFX_DUMP1(dc, "\nbm.bmPlanes = ", bm.bmPlanes);
  987.     AFX_DUMP1(dc, "\nbm.bmBitsPixel = ", bm.bmBitsPixel);
  988. }
  989. #endif
  990.  
  991. /////////////////////////////////////////////////////////////////////////////
  992.