home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / wingdi.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  34.5 KB  |  1,423 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 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 related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_CORE2_SEG
  14. #pragma code_seg(AFX_CORE2_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. /////////////////////////////////////////////////////////////////////////////
  23. // Diagnostic Output
  24. #ifdef _DEBUG
  25. CDumpContext& AFXAPI operator<<(CDumpContext& dc, SIZE size)
  26. {
  27.     return dc << "(" << size.cx << " x " << size.cy << ")";
  28. }
  29.  
  30. CDumpContext& AFXAPI operator<<(CDumpContext& dc, POINT point)
  31. {
  32.     return dc << "(" << point.x << ", " << point.y << ")";
  33. }
  34.  
  35. CDumpContext& AFXAPI operator<<(CDumpContext& dc, const RECT& rect)
  36. {
  37.     return dc << "(L " << rect.left << ", T " << rect.top << ", R " <<
  38.         rect.right << ", B " << rect.bottom << ")";
  39. }
  40. #endif //_DEBUG
  41.  
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CDC
  44.  
  45. CDC::CDC()
  46. {
  47.     m_hDC = NULL;
  48.     m_hAttribDC = NULL;
  49. #if !defined(_WIN32_WCE_NO_PRINTING)
  50.     m_bPrinting = FALSE;
  51. #endif // _WIN32_WCE_NO_PRINTING
  52. #if defined(_WIN32_WCE)
  53.     m_ptCurPos.x = 0;
  54.     m_ptCurPos.y = 0;
  55. #endif // _WIN32_WCE
  56. }
  57.  
  58. #ifdef _DEBUG
  59. void CDC::AssertValid() const
  60. {
  61.     CObject::AssertValid();
  62. }
  63.  
  64. void CDC::Dump(CDumpContext& dc) const
  65. {
  66.     CObject::Dump(dc);
  67.  
  68.     dc << "m_hDC = " << (UINT)m_hDC;
  69.     dc << "\nm_hAttribDC = " << (UINT)m_hAttribDC;
  70. #if !defined(_WIN32_WCE_NO_PRINTING)
  71.     dc << "\nm_bPrinting = " << m_bPrinting;
  72. #endif // _WIN32_WCE_NO_PRINTING
  73.  
  74.     dc << "\n";
  75. }
  76. #endif //_DEBUG
  77.  
  78. #if !defined(_WIN32_WCE)
  79. #include "fixalloc.h"
  80.  
  81. class CTempDC : public CDC
  82. {
  83.     DECLARE_DYNCREATE(CTempDC)
  84.     DECLARE_FIXED_ALLOC(CTempDC);
  85. };
  86. #endif // _WIN32_WCE
  87.  
  88. CHandleMap* PASCAL afxMapHDC(BOOL bCreate)
  89. {
  90.     AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  91.     if (pState->m_pmapHDC == NULL && bCreate)
  92.     {
  93.         BOOL bEnable = AfxEnableMemoryTracking(FALSE);
  94. #ifndef _AFX_PORTABLE
  95.         _PNH pnhOldHandler = AfxSetNewHandler(&AfxCriticalNewHandler);
  96. #endif
  97.         pState->m_pmapHDC = new CHandleMap(WCE_IF(RUNTIME_CLASS(CDC),RUNTIME_CLASS(CTempDC)),
  98.             offsetof(CDC, m_hDC), 2);
  99.  
  100. #ifndef _AFX_PORTABLE
  101.         AfxSetNewHandler(pnhOldHandler);
  102. #endif
  103.         AfxEnableMemoryTracking(bEnable);
  104.     }
  105.     return pState->m_pmapHDC;
  106. }
  107.  
  108. CDC* PASCAL CDC::FromHandle(HDC hDC)
  109. {
  110.     CHandleMap* pMap = afxMapHDC(TRUE); //create map if not exist
  111.     ASSERT(pMap != NULL);
  112.     CDC* pDC = (CDC*)pMap->FromHandle(hDC);
  113.     ASSERT(pDC == NULL || pDC->m_hDC == hDC);
  114.     return pDC;
  115. }
  116.  
  117. BOOL CDC::Attach(HDC hDC)
  118. {
  119.     ASSERT(m_hDC == NULL);      // only attach once, detach on destroy
  120.     ASSERT(m_hAttribDC == NULL);    // only attach to an empty DC
  121.  
  122.     if (hDC == NULL)
  123.         return FALSE;
  124.     CHandleMap* pMap = afxMapHDC(TRUE); // create map if not exist
  125.     ASSERT(pMap != NULL);
  126.     pMap->SetPermanent(m_hDC = hDC, this);
  127.  
  128.     SetAttribDC(m_hDC);     // Default to same as output
  129.     return TRUE;
  130. }
  131.  
  132. HDC CDC::Detach()
  133. {
  134.     HDC hDC = m_hDC;
  135.     if (hDC != NULL)
  136.     {
  137.         CHandleMap* pMap = afxMapHDC(); // don't create if not exist
  138.         if (pMap != NULL)
  139.             pMap->RemoveHandle(m_hDC);
  140.     }
  141.  
  142.     ReleaseAttribDC();
  143.     m_hDC = NULL;
  144.     return hDC;
  145. }
  146.  
  147. BOOL CDC::DeleteDC()
  148. {
  149.     if (m_hDC == NULL)
  150.         return FALSE;
  151.  
  152.     return ::DeleteDC(Detach());
  153. }
  154.  
  155. CDC::~CDC()
  156. {
  157.     if (m_hDC != NULL)
  158.         ::DeleteDC(Detach());
  159. }
  160.  
  161.  
  162. void CDC::SetAttribDC(HDC hDC)  // Set the Attribute DC
  163. {
  164.     m_hAttribDC = hDC;
  165. }
  166.  
  167. void CDC::SetOutputDC(HDC hDC)  // Set the Output DC
  168. {
  169. #ifdef _DEBUG
  170.     CHandleMap* pMap = afxMapHDC();
  171.     if (pMap != NULL && pMap->LookupPermanent(m_hDC) == this)
  172.     {
  173.         TRACE0("Cannot Set Output hDC on Attached CDC.\n");
  174.         ASSERT(FALSE);
  175.     }
  176. #endif
  177.     m_hDC = hDC;
  178. }
  179.  
  180. void CDC::ReleaseAttribDC()     // Release the Attribute DC
  181. {
  182.     m_hAttribDC = NULL;
  183. }
  184.  
  185. void CDC::ReleaseOutputDC()     // Release the Output DC
  186. {
  187. #ifdef _DEBUG
  188.     CHandleMap* pMap = afxMapHDC();
  189.     if (pMap != NULL && pMap->LookupPermanent(m_hDC) == this)
  190.     {
  191.         TRACE0("Cannot Release Output hDC on Attached CDC.\n");
  192.         ASSERT(FALSE);
  193.     }
  194. #endif
  195.     m_hDC = NULL;
  196. }
  197.  
  198. /////////////////////////////////////////////////////////////////////////////
  199. // Out-of-line routines
  200.  
  201. #if !defined(_WIN32_WCE_NO_PRINTING)
  202. int CDC::StartDoc(LPCTSTR lpszDocName)
  203. {
  204.     DOCINFO di;
  205.     memset(&di, 0, sizeof(DOCINFO));
  206.     di.cbSize = sizeof(DOCINFO);
  207.     di.lpszDocName = lpszDocName;
  208.     return StartDoc(&di);
  209. }
  210. #endif // _WIN32_WCE_NO_PRINTING
  211.  
  212. int CDC::SaveDC()
  213. {
  214.     ASSERT(m_hDC != NULL);
  215.     int nRetVal = 0;
  216.     if (m_hAttribDC != NULL)
  217.         nRetVal = ::SaveDC(m_hAttribDC);
  218.     if (m_hDC != m_hAttribDC && ::SaveDC(m_hDC) != 0)
  219.         nRetVal = -1;   // -1 is the only valid restore value for complex DCs
  220.     return nRetVal;
  221. }
  222.  
  223. BOOL CDC::RestoreDC(int nSavedDC)
  224. {
  225.     // if two distinct DCs, nSavedDC can only be -1
  226.     ASSERT(m_hDC != NULL);
  227.     ASSERT(m_hDC == m_hAttribDC || nSavedDC == -1);
  228.  
  229.     BOOL bRetVal = TRUE;
  230.     if (m_hDC != m_hAttribDC)
  231.         bRetVal = ::RestoreDC(m_hDC, nSavedDC);
  232.     if (m_hAttribDC != NULL)
  233.         bRetVal = (bRetVal && ::RestoreDC(m_hAttribDC, nSavedDC));
  234.     return bRetVal;
  235. }
  236.  
  237. CGdiObject* PASCAL CDC::SelectGdiObject(HDC hDC, HGDIOBJ h)
  238. {
  239.     return CGdiObject::FromHandle(::SelectObject(hDC, h));
  240. }
  241.  
  242. CGdiObject* CDC::SelectStockObject(int nIndex)
  243. {
  244.     ASSERT(m_hDC != NULL);
  245.  
  246.     HGDIOBJ hObject = ::GetStockObject(nIndex);
  247.     HGDIOBJ hOldObj = NULL;
  248.  
  249.     ASSERT(hObject != NULL);
  250.     if (m_hDC != m_hAttribDC)
  251.         hOldObj = ::SelectObject(m_hDC, hObject);
  252.     if (m_hAttribDC != NULL)
  253.         hOldObj = ::SelectObject(m_hAttribDC, hObject);
  254.     return CGdiObject::FromHandle(hOldObj);
  255. }
  256.  
  257. CPen* CDC::SelectObject(CPen* pPen)
  258. {
  259.     ASSERT(m_hDC != NULL);
  260.     HGDIOBJ hOldObj = NULL;
  261.  
  262.     if (m_hDC != m_hAttribDC)
  263.         hOldObj = ::SelectObject(m_hDC, pPen->GetSafeHandle());
  264.     if (m_hAttribDC != NULL)
  265.         hOldObj = ::SelectObject(m_hAttribDC, pPen->GetSafeHandle());
  266.     return (CPen*)CGdiObject::FromHandle(hOldObj);
  267. }
  268.  
  269. CBrush* CDC::SelectObject(CBrush* pBrush)
  270. {
  271.     ASSERT(m_hDC != NULL);
  272.     HGDIOBJ hOldObj = NULL;
  273.  
  274.     if (m_hDC != m_hAttribDC)
  275.         hOldObj = ::SelectObject(m_hDC, pBrush->GetSafeHandle());
  276.     if (m_hAttribDC != NULL)
  277.         hOldObj = ::SelectObject(m_hAttribDC, pBrush->GetSafeHandle());
  278.     return (CBrush*)CGdiObject::FromHandle(hOldObj);
  279. }
  280.  
  281. CFont* CDC::SelectObject(CFont* pFont)
  282. {
  283.     ASSERT(m_hDC != NULL);
  284.     HGDIOBJ hOldObj = NULL;
  285.  
  286.     if (m_hDC != m_hAttribDC)
  287.         hOldObj = ::SelectObject(m_hDC, pFont->GetSafeHandle());
  288.     if (m_hAttribDC != NULL)
  289.         hOldObj = ::SelectObject(m_hAttribDC, pFont->GetSafeHandle());
  290.     return (CFont*)CGdiObject::FromHandle(hOldObj);
  291. }
  292.  
  293. int CDC::SelectObject(CRgn* pRgn)
  294. {
  295.     ASSERT(m_hDC != NULL);
  296.     int nRetVal = GDI_ERROR;
  297.  
  298.     if (m_hDC != m_hAttribDC)
  299.         nRetVal = (int)::SelectObject(m_hDC, pRgn->GetSafeHandle());
  300.     if (m_hAttribDC != NULL)
  301.         nRetVal = (int)::SelectObject(m_hAttribDC, pRgn->GetSafeHandle());
  302.     return nRetVal;
  303. }
  304.  
  305. CPalette* CDC::SelectPalette(CPalette* pPalette, BOOL bForceBackground)
  306. {
  307.     ASSERT(m_hDC != NULL);
  308.  
  309.     return (CPalette*) CGdiObject::FromHandle(::SelectPalette(m_hDC,
  310.         (HPALETTE)pPalette->GetSafeHandle(), bForceBackground));
  311. }
  312.  
  313. COLORREF CDC::SetBkColor(COLORREF crColor)
  314. {
  315.     ASSERT(m_hDC != NULL);
  316.     COLORREF crRetVal = CLR_INVALID; 
  317.  
  318.     if (m_hDC != m_hAttribDC)
  319.         crRetVal = ::SetBkColor(m_hDC, crColor);
  320.     if (m_hAttribDC != NULL)
  321.         crRetVal = ::SetBkColor(m_hAttribDC, crColor);
  322.     return crRetVal;
  323. }
  324.  
  325. int CDC::SetBkMode(int nBkMode)
  326. {
  327.     ASSERT(m_hDC != NULL);
  328.     int nRetVal = 0;
  329.  
  330.     if (m_hDC != m_hAttribDC)
  331.         nRetVal = ::SetBkMode(m_hDC, nBkMode);
  332.     if (m_hAttribDC != NULL)
  333.         nRetVal = ::SetBkMode(m_hAttribDC, nBkMode);
  334.     return nRetVal;
  335. }
  336.  
  337. #if !defined(_WIN32_WCE)
  338. int CDC::SetPolyFillMode(int nPolyFillMode)
  339. {
  340.     ASSERT(m_hDC != NULL);
  341.     int nRetVal = 0;
  342.  
  343.     if (m_hDC != m_hAttribDC)
  344.         nRetVal = ::SetPolyFillMode(m_hDC, nPolyFillMode);
  345.     if (m_hAttribDC != NULL)
  346.         nRetVal = ::SetPolyFillMode(m_hAttribDC, nPolyFillMode);
  347.     return nRetVal;
  348. }
  349. #endif // _WIN32_WCE
  350.  
  351. int CDC::SetROP2(int nDrawMode)
  352. {
  353.     ASSERT(m_hDC != NULL);
  354.     int nRetVal = 0;
  355.  
  356.     if (m_hDC != m_hAttribDC)
  357.         nRetVal = ::SetROP2(m_hDC, nDrawMode);
  358.     if (m_hAttribDC != NULL)
  359.         nRetVal = ::SetROP2(m_hAttribDC, nDrawMode);
  360.     return nRetVal;
  361. }
  362.  
  363. #if !defined(_WIN32_WCE)
  364. int CDC::SetStretchBltMode(int nStretchMode)
  365. {
  366.     ASSERT(m_hDC != NULL);
  367.     int nRetVal = 0;
  368.  
  369.     if (m_hDC != m_hAttribDC)
  370.         nRetVal = ::SetStretchBltMode(m_hDC, nStretchMode);
  371.     if (m_hAttribDC != NULL)
  372.         nRetVal = ::SetStretchBltMode(m_hAttribDC, nStretchMode);
  373.     return nRetVal;
  374. }
  375. #endif // _WIN32_WCE
  376.  
  377. COLORREF CDC::SetTextColor(COLORREF crColor)
  378. {
  379.     ASSERT(m_hDC != NULL);
  380.     COLORREF crRetVal = CLR_INVALID;
  381.  
  382.     if (m_hDC != m_hAttribDC)
  383.         crRetVal = ::SetTextColor(m_hDC, crColor);
  384.     if (m_hAttribDC != NULL)
  385.         crRetVal = ::SetTextColor(m_hAttribDC, crColor);
  386.     return crRetVal;
  387. }
  388.  
  389. #if !defined(_WIN32_WCE_NO_GDITRANSFORM)
  390. int CDC::SetMapMode(int nMapMode)
  391. {
  392.     ASSERT(m_hDC != NULL);
  393.     int nRetVal = 0;
  394.  
  395.     if (m_hDC != m_hAttribDC)
  396.         nRetVal = ::SetMapMode(m_hDC, nMapMode);
  397.     if (m_hAttribDC != NULL)
  398.         nRetVal = ::SetMapMode(m_hAttribDC, nMapMode);
  399.     return nRetVal;
  400. }
  401.  
  402. CPoint CDC::SetViewportOrg(int x, int y)
  403. {
  404.     ASSERT(m_hDC != NULL);
  405.     CPoint point;
  406.  
  407.     if (m_hDC != m_hAttribDC)
  408.         VERIFY(::SetViewportOrgEx(m_hDC, x, y, &point));
  409.     if (m_hAttribDC != NULL)
  410.         VERIFY(::SetViewportOrgEx(m_hAttribDC, x, y, &point));
  411.     return point;
  412. }
  413.  
  414. CPoint CDC::OffsetViewportOrg(int nWidth, int nHeight)
  415. {
  416.     ASSERT(m_hDC != NULL);
  417.     CPoint point;
  418.  
  419.     if (m_hDC != m_hAttribDC)
  420.         VERIFY(::OffsetViewportOrgEx(m_hDC, nWidth, nHeight, &point));
  421.     if (m_hAttribDC != NULL)
  422.         VERIFY(::OffsetViewportOrgEx(m_hAttribDC, nWidth, nHeight, &point));
  423.     return point;
  424. }
  425.  
  426. CSize CDC::SetViewportExt(int x, int y)
  427. {
  428.     ASSERT(m_hDC != NULL);
  429.     CSize size;
  430.     
  431.     if (m_hDC != m_hAttribDC)
  432.         VERIFY(::SetViewportExtEx(m_hDC, x, y, &size));
  433.     if (m_hAttribDC != NULL)
  434.         VERIFY(::SetViewportExtEx(m_hAttribDC, x, y, &size));
  435.     return size;
  436. }
  437.  
  438. CSize CDC::ScaleViewportExt(int xNum, int xDenom, int yNum, int yDenom)
  439. {
  440.     ASSERT(m_hDC != NULL);
  441.     CSize size;
  442.  
  443.     if (m_hDC != m_hAttribDC)
  444.         VERIFY(::ScaleViewportExtEx(m_hDC, xNum, xDenom, yNum, yDenom, &size));
  445.     if (m_hAttribDC != NULL)
  446.         VERIFY(::ScaleViewportExtEx(m_hAttribDC, xNum, xDenom, yNum, yDenom, &size));
  447.     return size;
  448. }
  449.  
  450. CPoint CDC::SetWindowOrg(int x, int y)
  451. {
  452.     ASSERT(m_hDC != NULL);
  453.     CPoint point;
  454.     
  455.     if (m_hDC != m_hAttribDC)
  456.         VERIFY(::SetWindowOrgEx(m_hDC, x, y, &point));
  457.     if (m_hAttribDC != NULL)
  458.         VERIFY(::SetWindowOrgEx(m_hAttribDC, x, y, &point));
  459.     return point;
  460. }
  461.  
  462. CPoint CDC::OffsetWindowOrg(int nWidth, int nHeight)
  463. {
  464.     ASSERT(m_hDC != NULL);
  465.     CPoint point;
  466.  
  467.     if (m_hDC != m_hAttribDC)
  468.         VERIFY(::OffsetWindowOrgEx(m_hDC, nWidth, nHeight, &point));
  469.     if (m_hAttribDC != NULL)
  470.         VERIFY(::OffsetWindowOrgEx(m_hAttribDC, nWidth, nHeight, &point));
  471.     return point;
  472. }
  473.  
  474. CSize CDC::SetWindowExt(int x, int y)
  475. {
  476.     ASSERT(m_hDC != NULL);
  477.     CSize size;
  478.  
  479.     if (m_hDC != m_hAttribDC)
  480.         VERIFY(::SetWindowExtEx(m_hDC, x, y, &size));
  481.     if (m_hAttribDC != NULL)
  482.         VERIFY(::SetWindowExtEx(m_hAttribDC, x, y, &size));
  483.     return size;
  484. }
  485.  
  486. CSize CDC::ScaleWindowExt(int xNum, int xDenom, int yNum, int yDenom)
  487. {
  488.     ASSERT(m_hDC != NULL);
  489.     CSize size;
  490.  
  491.     if (m_hDC != m_hAttribDC)
  492.         VERIFY(::ScaleWindowExtEx(m_hDC, xNum, xDenom, yNum, yDenom, &size));
  493.     if (m_hAttribDC != NULL)
  494.         VERIFY(::ScaleWindowExtEx(m_hAttribDC, xNum, xDenom, yNum, yDenom, &size));
  495.     return size;
  496. }
  497. #endif // _WIN32_WCE_NO_GDITRANSFORM
  498.  
  499. int CDC::GetClipBox(LPRECT lpRect) const
  500. {
  501.     ASSERT(m_hDC != NULL);
  502.     return ::GetClipBox(m_hDC, lpRect);
  503. }
  504.  
  505. int CDC::SelectClipRgn(CRgn* pRgn)
  506. {
  507.     ASSERT(m_hDC != NULL);
  508.     int nRetVal = ERROR;
  509.  
  510.     if (m_hDC != m_hAttribDC)
  511.         nRetVal = ::SelectClipRgn(m_hDC, (HRGN)pRgn->GetSafeHandle());
  512.     if (m_hAttribDC != NULL)
  513.         nRetVal = ::SelectClipRgn(m_hAttribDC, (HRGN)pRgn->GetSafeHandle());
  514.     return nRetVal;
  515. }
  516.  
  517. int CDC::ExcludeClipRect(int x1, int y1, int x2, int y2)
  518. {
  519.     ASSERT(m_hDC != NULL);
  520.     int nRetVal = ERROR;
  521.  
  522.     if (m_hDC != m_hAttribDC)
  523.         nRetVal = ::ExcludeClipRect(m_hDC, x1, y1, x2, y2);
  524.     if (m_hAttribDC != NULL)
  525.         nRetVal = ::ExcludeClipRect(m_hAttribDC, x1, y1, x2, y2);
  526.     return nRetVal;
  527. }
  528.  
  529. int CDC::ExcludeClipRect(LPCRECT lpRect)
  530. {
  531.     ASSERT(m_hDC != NULL);
  532.     int nRetVal = ERROR;
  533.  
  534.     if (m_hDC != m_hAttribDC)
  535.         nRetVal = ::ExcludeClipRect(m_hDC, lpRect->left, lpRect->top,
  536.             lpRect->right, lpRect->bottom);
  537.     if (m_hAttribDC != NULL)
  538.         nRetVal = ::ExcludeClipRect(m_hAttribDC, lpRect->left, lpRect->top,
  539.             lpRect->right, lpRect->bottom);
  540.     return nRetVal;
  541. }
  542.  
  543. int CDC::IntersectClipRect(int x1, int y1, int x2, int y2)
  544. {
  545.     ASSERT(m_hDC != NULL);
  546.     int nRetVal = ERROR;
  547.  
  548.     if (m_hDC != m_hAttribDC)
  549.         nRetVal = ::IntersectClipRect(m_hDC, x1, y1, x2, y2);
  550.     if (m_hAttribDC != NULL)
  551.         nRetVal = ::IntersectClipRect(m_hAttribDC, x1, y1, x2, y2);
  552.     return nRetVal;
  553. }
  554.  
  555. int CDC::IntersectClipRect(LPCRECT lpRect)
  556. {
  557.     ASSERT(m_hDC != NULL);
  558.     int nRetVal = ERROR;
  559.  
  560.     if (m_hDC != m_hAttribDC)
  561.         nRetVal = ::IntersectClipRect(m_hDC, lpRect->left, lpRect->top,
  562.             lpRect->right, lpRect->bottom);
  563.     if (m_hAttribDC != NULL)
  564.         nRetVal = ::IntersectClipRect(m_hAttribDC, lpRect->left, lpRect->top,
  565.             lpRect->right, lpRect->bottom);
  566.     return nRetVal;
  567. }
  568.  
  569. int CDC::OffsetClipRgn(int x, int y)
  570. {
  571.     ASSERT(m_hDC != NULL);
  572.     int nRetVal = ERROR;
  573.  
  574.     if (m_hDC != m_hAttribDC)
  575.         nRetVal = ::WCE_FCTN(OffsetClipRgn)(m_hDC, x, y);
  576.     if (m_hAttribDC != NULL)
  577.         nRetVal = ::WCE_FCTN(OffsetClipRgn)(m_hAttribDC, x, y);
  578.     return nRetVal;
  579. }
  580.  
  581. int CDC::OffsetClipRgn(SIZE size)
  582. {
  583.     ASSERT(m_hDC != NULL);
  584.     int nRetVal = ERROR;
  585.  
  586.     if (m_hDC != m_hAttribDC)
  587.         nRetVal = ::WCE_FCTN(OffsetClipRgn)(m_hDC, size.cx, size.cy);
  588.     if (m_hAttribDC != NULL)
  589.         nRetVal = ::WCE_FCTN(OffsetClipRgn)(m_hAttribDC, size.cx, size.cy);
  590.     return nRetVal;
  591. }
  592.  
  593. #if defined(_WIN32_WCE)
  594. CPoint CDC::MoveTo(int x, int y) 
  595.     CPoint ptOld(m_ptCurPos); 
  596.     m_ptCurPos.x = x; 
  597.     m_ptCurPos.y = y; 
  598.     return ptOld; 
  599.  
  600. BOOL CDC::LineTo(int x, int y) 
  601.     ASSERT(m_hDC != NULL); 
  602.     CPoint ptTo(x,y); 
  603.     CPoint points[2] = { m_ptCurPos, ptTo }; 
  604.     BOOL bResult = ::Polyline(m_hDC, points, 2); 
  605.     if (bResult)  
  606.         m_ptCurPos = ptTo; 
  607.     return bResult; 
  608. #else // _WIN32_WCE
  609. CPoint CDC::MoveTo(int x, int y)
  610. {
  611.     ASSERT(m_hDC != NULL);
  612.     CPoint point;
  613.  
  614.     if (m_hDC != m_hAttribDC)
  615.         VERIFY(::MoveToEx(m_hDC, x, y, &point));
  616.     if (m_hAttribDC != NULL)
  617.         VERIFY(::MoveToEx(m_hAttribDC, x, y, &point));
  618.     return point;
  619. }
  620.  
  621. BOOL CDC::LineTo(int x, int y)
  622. {
  623.     ASSERT(m_hDC != NULL);
  624.     if (m_hAttribDC != NULL && m_hDC != m_hAttribDC)
  625.         ::MoveToEx(m_hAttribDC, x, y, NULL);
  626.     return ::LineTo(m_hDC, x, y);
  627. }
  628. #endif // _WIN32_WCE
  629.  
  630. #if !defined(_WIN32_WCE)
  631. UINT CDC::SetTextAlign(UINT nFlags)
  632. {
  633.     ASSERT(m_hDC != NULL);
  634.     UINT nRetVal = GDI_ERROR;
  635.  
  636.     if (m_hDC != m_hAttribDC)
  637.         ::SetTextAlign(m_hDC, nFlags);
  638.     if (m_hAttribDC != NULL)
  639.         nRetVal = ::SetTextAlign(m_hAttribDC, nFlags);
  640.     return nRetVal;
  641. }
  642.  
  643. int CDC::SetTextJustification(int nBreakExtra, int nBreakCount)
  644. {
  645.     ASSERT(m_hDC != NULL);
  646.     int nRetVal = 0;
  647.  
  648.     if (m_hDC != m_hAttribDC)
  649.         nRetVal = ::SetTextJustification(m_hDC, nBreakExtra, nBreakCount);
  650.     if (m_hAttribDC != NULL)
  651.         nRetVal = ::SetTextJustification(m_hAttribDC, nBreakExtra, nBreakCount);
  652.     return nRetVal;
  653. }
  654.  
  655. int CDC::SetTextCharacterExtra(int nCharExtra)
  656. {
  657.     ASSERT(m_hDC != NULL);
  658.     int nRetVal = 0x8000000;
  659.     if (m_hDC != m_hAttribDC)
  660.         nRetVal = ::SetTextCharacterExtra(m_hDC, nCharExtra);
  661.     if (m_hAttribDC != NULL)
  662.         nRetVal = ::SetTextCharacterExtra(m_hAttribDC, nCharExtra);
  663.     return nRetVal;
  664. }
  665.  
  666. DWORD CDC::SetMapperFlags(DWORD dwFlag)
  667. {
  668.     ASSERT(m_hDC != NULL);
  669.     DWORD dwRetVal = GDI_ERROR;
  670.     if (m_hDC != m_hAttribDC)
  671.         dwRetVal = ::SetMapperFlags(m_hDC, dwFlag);
  672.     if (m_hAttribDC != NULL)
  673.         dwRetVal = ::SetMapperFlags(m_hAttribDC, dwFlag);
  674.     return dwRetVal;
  675. }
  676.  
  677. typedef DWORD (CALLBACK* AFX_GDIGETLAYOUTPROC)(HDC);
  678. typedef DWORD (CALLBACK* AFX_GDISETLAYOUTPROC)(HDC, DWORD);
  679.  
  680. DWORD CDC::GetLayout() const
  681. {
  682.     ASSERT(m_hDC != NULL);
  683.  
  684.     HINSTANCE hInst = ::GetModuleHandleA("GDI32.DLL");
  685.     ASSERT(hInst != NULL);
  686.  
  687.     DWORD dwGetLayout = LAYOUT_LTR;
  688.  
  689.     AFX_GDIGETLAYOUTPROC pfn;
  690.     pfn = (AFX_GDIGETLAYOUTPROC) GetProcAddress(hInst, "GetLayout");
  691.     
  692.     if (pfn != NULL)
  693.         dwGetLayout = (*pfn)(m_hDC);
  694.     
  695.     return dwGetLayout;
  696. }
  697.  
  698. DWORD CDC::SetLayout(DWORD dwSetLayout)
  699. {
  700.     ASSERT(m_hDC != NULL);
  701.  
  702.     HINSTANCE hInst = ::GetModuleHandleA("GDI32.DLL");
  703.     ASSERT(hInst != NULL);
  704.  
  705.     DWORD dwGetLayout = LAYOUT_LTR;
  706.  
  707.     AFX_GDISETLAYOUTPROC pfn;
  708.     pfn = (AFX_GDISETLAYOUTPROC) GetProcAddress(hInst, "SetLayout");
  709.     
  710.     if (pfn != NULL)
  711.         dwGetLayout = (*pfn)(m_hDC, dwSetLayout);
  712.     else if (dwSetLayout == 0)
  713.     {
  714.         dwGetLayout = GDI_ERROR;
  715.         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  716.     }
  717.     
  718.     return dwGetLayout;
  719. }
  720. #endif // _WIN32_WCE
  721.  
  722. /////////////////////////////////////////////////////////////////////////////
  723. // Advanced Win32 GDI functions
  724.  
  725. #if !defined(_WIN32_WCE) 
  726. BOOL CDC::ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
  727. {
  728.     ASSERT(m_hDC != NULL);
  729.     BOOL bResult = ::ArcTo(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
  730.     if (m_hDC != m_hAttribDC)
  731.     {
  732.         CPoint pt;
  733.         VERIFY(::GetCurrentPositionEx(m_hDC, &pt));
  734.         VERIFY(::MoveToEx(m_hAttribDC, pt.x, pt.y, NULL));
  735.     }
  736.     return bResult;
  737. }
  738.  
  739. int CDC::SetArcDirection(int nArcDirection)
  740. {
  741.     ASSERT(m_hDC != NULL);
  742.     int nResult = 0;
  743.     if (m_hDC != m_hAttribDC)
  744.         nResult = ::SetArcDirection(m_hDC, nArcDirection);
  745.     if (m_hAttribDC != NULL)
  746.         nResult = ::SetArcDirection(m_hAttribDC, nArcDirection);
  747.     return nResult;
  748. }
  749.  
  750. BOOL CDC::PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount)
  751. {
  752.     ASSERT(m_hDC != NULL);
  753.     BOOL bResult = ::PolyDraw(m_hDC, lpPoints, lpTypes, nCount);
  754.     if (m_hDC != m_hAttribDC)
  755.     {
  756.         CPoint pt;
  757.         VERIFY(::GetCurrentPositionEx(m_hDC, &pt));
  758.         VERIFY(::MoveToEx(m_hAttribDC, pt.x, pt.y, NULL));
  759.     }
  760.     return bResult;
  761. }
  762. #endif // _WIN32_WCE
  763.  
  764. #if defined(_WIN32_WCE)
  765. BOOL CDC::PolylineTo(const POINT* lpPoints, int nCount)
  766. {
  767.     ASSERT(m_hDC != NULL);
  768.     CPoint firstSeg[2] = { m_ptCurPos, lpPoints[0] };
  769.     BOOL bResult = ::Polyline(m_hDC, firstSeg, 2);
  770.     if (bResult) 
  771.     {
  772.         bResult = ::Polyline(m_hDC, lpPoints, nCount);
  773.         if (bResult) 
  774.             m_ptCurPos = lpPoints[nCount-1];
  775.     }
  776.     return bResult;
  777. }
  778. #else // _WIN32_WCE
  779. BOOL CDC::PolylineTo(const POINT* lpPoints, int nCount)
  780. {
  781.     ASSERT(m_hDC != NULL);
  782.     BOOL bResult = ::PolylineTo(m_hDC, lpPoints, nCount);
  783.     if (m_hDC != m_hAttribDC)
  784.     {
  785.         CPoint pt;
  786.         VERIFY(::GetCurrentPositionEx(m_hDC, &pt));
  787.         VERIFY(::MoveToEx(m_hAttribDC, pt.x, pt.y, NULL));
  788.     }
  789.     return bResult;
  790. }
  791. #endif // _WIN32_WCE
  792.  
  793. #if !defined(_WIN32_WCE)
  794. BOOL CDC::SetColorAdjustment(const COLORADJUSTMENT* lpColorAdjust)
  795. {
  796.     ASSERT(m_hDC != NULL);
  797.     BOOL bResult = FALSE;
  798.     if (m_hDC != m_hAttribDC)
  799.         bResult = ::SetColorAdjustment(m_hDC, lpColorAdjust);
  800.     if (m_hAttribDC != NULL)
  801.         bResult = ::SetColorAdjustment(m_hAttribDC, lpColorAdjust);
  802.     return bResult;
  803. }
  804.  
  805. BOOL CDC::PolyBezierTo(const POINT* lpPoints, int nCount)
  806. {
  807.     ASSERT(m_hDC != NULL);
  808.     BOOL bResult = ::PolyBezierTo(m_hDC, lpPoints, nCount);
  809.     if (m_hDC != m_hAttribDC)
  810.     {
  811.         CPoint pt;
  812.         VERIFY(::GetCurrentPositionEx(m_hDC, &pt));
  813.         VERIFY(::MoveToEx(m_hAttribDC, pt.x, pt.y, NULL));
  814.     }
  815.     return bResult;
  816. }
  817.  
  818. BOOL CDC::SelectClipPath(int nMode)
  819. {
  820.     ASSERT(m_hDC != NULL);
  821.  
  822.     // output DC always holds the current path
  823.     if (!::SelectClipPath(m_hDC, nMode))
  824.         return FALSE;
  825.  
  826.     // transfer clipping region into the attribute DC
  827.     BOOL bResult = TRUE;
  828.     if (m_hDC != m_hAttribDC)
  829.     {
  830.         HRGN hRgn = ::CreateRectRgn(0, 0, 0, 0);
  831.         if (::GetClipRgn(m_hDC, hRgn) < 0 || !::SelectClipRgn(m_hAttribDC, hRgn))
  832.         {
  833.             TRACE0("Error: unable to transfer clip region in CDC::SelectClipPath!\n");
  834.             bResult = FALSE;
  835.         }
  836.         DeleteObject(hRgn);
  837.     }
  838.     return bResult;
  839. }
  840. #endif // _WIN32_WCE
  841.  
  842. int CDC::SelectClipRgn(CRgn* pRgn, int nMode)
  843. {
  844.     ASSERT(m_hDC != NULL);
  845.     int nRetVal = ERROR;
  846.     if (m_hDC != m_hAttribDC)
  847.         nRetVal = ::WCE_FCTN(ExtSelectClipRgn)(m_hDC, (HRGN)pRgn->GetSafeHandle(), nMode);
  848.     if (m_hAttribDC != NULL)
  849.         nRetVal = ::WCE_FCTN(ExtSelectClipRgn)(m_hAttribDC, (HRGN)pRgn->GetSafeHandle(), nMode);
  850.     return nRetVal;
  851. }
  852.  
  853. /////////////////////////////////////////////////////////////////////////////
  854. // Special handling for metafile playback
  855.  
  856. #if !defined(_WIN32_WCE)
  857. int CALLBACK AfxEnumMetaFileProc(HDC hDC,
  858.     HANDLETABLE* pHandleTable, METARECORD* pMetaRec, int nHandles, LPARAM lParam)
  859. {
  860.     CDC* pDC = (CDC*)lParam;
  861.     ASSERT_VALID(pDC);
  862.  
  863.     switch (pMetaRec->rdFunction)
  864.     {
  865.     // these records have effects different for each CDC derived class
  866.     case META_SETMAPMODE:
  867.         pDC->SetMapMode((int)(short)pMetaRec->rdParm[0]);
  868.         break;
  869.     case META_SETWINDOWEXT:
  870.         pDC->SetWindowExt(
  871.             (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  872.         break;
  873.     case META_SETWINDOWORG:
  874.         pDC->SetWindowOrg(
  875.             (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  876.         break;
  877.     case META_SETVIEWPORTEXT:
  878.         pDC->SetViewportExt(
  879.             (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  880.         break;
  881.     case META_SETVIEWPORTORG:
  882.         pDC->SetViewportOrg(
  883.             (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  884.         break;
  885.     case META_SCALEWINDOWEXT:
  886.         pDC->ScaleWindowExt(
  887.             (int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
  888.             (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  889.         break;
  890.     case META_SCALEVIEWPORTEXT:
  891.         pDC->ScaleViewportExt(
  892.             (int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
  893.             (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  894.         break;
  895.     case META_OFFSETVIEWPORTORG:
  896.         pDC->OffsetViewportOrg(
  897.             (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  898.         break;
  899.     case META_SAVEDC:
  900.         pDC->SaveDC();
  901.         break;
  902.     case META_RESTOREDC:
  903.         pDC->RestoreDC((int)(short)pMetaRec->rdParm[0]);
  904.         break;
  905.     case META_SETBKCOLOR:
  906.         pDC->SetBkColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
  907.         break;
  908.     case META_SETTEXTCOLOR:
  909.         pDC->SetTextColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
  910.         break;
  911.  
  912.     // need to watch out for SelectObject(HFONT), for custom font mapping
  913.     case META_SELECTOBJECT:
  914.         {
  915.             HGDIOBJ hObject = pHandleTable->objectHandle[pMetaRec->rdParm[0]];
  916.             UINT nObjType = GetObjectType(hObject);
  917.             if (nObjType == 0)
  918.             {
  919.                 // object type is unknown, determine if it is a font
  920.                 HFONT hStockFont = (HFONT)::GetStockObject(SYSTEM_FONT);
  921.                 HFONT hFontOld = (HFONT)::SelectObject(pDC->m_hDC, hStockFont);
  922.                 HGDIOBJ hObjOld = ::SelectObject(pDC->m_hDC, hObject);
  923.                 if (hObjOld == hStockFont)
  924.                 {
  925.                     // got the stock object back, so must be selecting a font
  926.                     pDC->SelectObject(CFont::FromHandle((HFONT)hObject));
  927.                     break;  // don't play the default record
  928.                 }
  929.                 else
  930.                 {
  931.                     // didn't get the stock object back, so restore everything
  932.                     ::SelectObject(pDC->m_hDC, hFontOld);
  933.                     ::SelectObject(pDC->m_hDC, hObjOld);
  934.                 }
  935.                 // and fall through to PlayMetaFileRecord...
  936.             }
  937.             else if (nObjType == OBJ_FONT)
  938.             {
  939.                 // play back as CDC::SelectObject(CFont*)
  940.                 pDC->SelectObject(CFont::FromHandle((HFONT)hObject));
  941.                 break;  // don't play the default record
  942.             }
  943.         }
  944.         // fall through...
  945.  
  946.     default:
  947.         ::PlayMetaFileRecord(hDC, pHandleTable, pMetaRec, nHandles);
  948.         break;
  949.     }
  950.  
  951.     return 1;
  952. }
  953.  
  954. BOOL CDC::PlayMetaFile(HMETAFILE hMF)
  955. {
  956.     if (::GetDeviceCaps(m_hDC, TECHNOLOGY) == DT_METAFILE)
  957.     {
  958.         // playing metafile in metafile, just use core windows API
  959.         return ::PlayMetaFile(m_hDC, hMF);
  960.     }
  961.  
  962.     // for special playback, lParam == pDC
  963.     return ::EnumMetaFile(m_hDC, hMF, AfxEnumMetaFileProc, (LPARAM)this);
  964. }
  965. #endif // _WIN32_WCE
  966.  
  967. /////////////////////////////////////////////////////////////////////////////
  968. // Coordinate transforms
  969.  
  970. void CDC::LPtoDP(LPSIZE lpSize) const
  971. {
  972.     ASSERT(AfxIsValidAddress(lpSize, sizeof(SIZE)));
  973.  
  974.     CSize sizeWinExt = GetWindowExt();
  975.     CSize sizeVpExt = GetViewportExt();
  976.     lpSize->cx = WCE_FCTN(MulDiv)(lpSize->cx, abs(sizeVpExt.cx), abs(sizeWinExt.cx));
  977.     lpSize->cy = WCE_FCTN(MulDiv)(lpSize->cy, abs(sizeVpExt.cy), abs(sizeWinExt.cy));
  978. }
  979.  
  980. void CDC::DPtoLP(LPSIZE lpSize) const
  981. {
  982.     ASSERT(AfxIsValidAddress(lpSize, sizeof(SIZE)));
  983.  
  984.     CSize sizeWinExt = GetWindowExt();
  985.     CSize sizeVpExt = GetViewportExt();
  986.     lpSize->cx = WCE_FCTN(MulDiv)(lpSize->cx, abs(sizeWinExt.cx), abs(sizeVpExt.cx));
  987.     lpSize->cy = WCE_FCTN(MulDiv)(lpSize->cy, abs(sizeWinExt.cy), abs(sizeVpExt.cy));
  988. }
  989.  
  990. /////////////////////////////////////////////////////////////////////////////
  991. // Helper DCs
  992.  
  993. #ifdef _DEBUG
  994. void CClientDC::AssertValid() const
  995. {
  996.     CDC::AssertValid();
  997.     ASSERT(m_hWnd == NULL || ::IsWindow(m_hWnd));
  998. }
  999.  
  1000. void CClientDC::Dump(CDumpContext& dc) const
  1001. {
  1002.     CDC::Dump(dc);
  1003.  
  1004.     dc << "m_hWnd = " << (UINT)m_hWnd;
  1005.     dc << "\n";
  1006. }
  1007. #endif
  1008.  
  1009. CClientDC::CClientDC(CWnd* pWnd)
  1010. {
  1011.     ASSERT(pWnd == NULL || ::IsWindow(pWnd->m_hWnd));
  1012.  
  1013.     if (!Attach(::GetDC(m_hWnd = pWnd->GetSafeHwnd())))
  1014.         AfxThrowResourceException();
  1015. }
  1016.  
  1017. CClientDC::~CClientDC()
  1018. {
  1019.     ASSERT(m_hDC != NULL);
  1020.     ::ReleaseDC(m_hWnd, Detach());
  1021. }
  1022.  
  1023. #ifdef _DEBUG
  1024. void CWindowDC::AssertValid() const
  1025. {
  1026.     CDC::AssertValid();
  1027.     ASSERT(m_hWnd == NULL || ::IsWindow(m_hWnd));
  1028. }
  1029.  
  1030. void CWindowDC::Dump(CDumpContext& dc) const
  1031. {
  1032.     CDC::Dump(dc);
  1033.  
  1034.     dc << "m_hWnd = " << (UINT)m_hWnd;
  1035.     dc << "\n";
  1036. }
  1037. #endif
  1038.  
  1039. CWindowDC::CWindowDC(CWnd* pWnd)
  1040. {
  1041.     ASSERT(pWnd == NULL || ::IsWindow(pWnd->m_hWnd));
  1042.  
  1043.     if (!Attach(::GetWindowDC(m_hWnd = pWnd->GetSafeHwnd())))
  1044.         AfxThrowResourceException();
  1045. }
  1046.  
  1047. CWindowDC::~CWindowDC()
  1048. {
  1049.     ASSERT(m_hDC != NULL);
  1050.     ::ReleaseDC(m_hWnd, Detach());
  1051. }
  1052.  
  1053. #ifdef _DEBUG
  1054. void CPaintDC::AssertValid() const
  1055. {
  1056.     CDC::AssertValid();
  1057.     ASSERT(::IsWindow(m_hWnd));
  1058. }
  1059.  
  1060. void CPaintDC::Dump(CDumpContext& dc) const
  1061. {
  1062.     CDC::Dump(dc);
  1063.  
  1064.     dc << "m_hWnd = " << (UINT)m_hWnd;
  1065.     dc << "\nm_ps.hdc = " << (UINT)m_ps.hdc;
  1066.     dc << "\nm_ps.fErase = " << m_ps.fErase;
  1067.     dc << "\nm_ps.rcPaint = " << (CRect)m_ps.rcPaint;
  1068.  
  1069.     dc << "\n";
  1070. }
  1071. #endif
  1072.  
  1073. CPaintDC::CPaintDC(CWnd* pWnd)
  1074. {
  1075.     ASSERT_VALID(pWnd);
  1076.     ASSERT(::IsWindow(pWnd->m_hWnd));
  1077.  
  1078.     if (!Attach(::BeginPaint(m_hWnd = pWnd->m_hWnd, &m_ps)))
  1079.         AfxThrowResourceException();
  1080. }
  1081.  
  1082. CPaintDC::~CPaintDC()
  1083. {
  1084.     ASSERT(m_hDC != NULL);
  1085.     ASSERT(::IsWindow(m_hWnd));
  1086.  
  1087.     ::EndPaint(m_hWnd, &m_ps);
  1088.     Detach();
  1089. }
  1090.  
  1091. /////////////////////////////////////////////////////////////////////////////
  1092. // CGdiObject
  1093.  
  1094. #ifdef _DEBUG
  1095. void CGdiObject::Dump(CDumpContext& dc) const
  1096. {
  1097.     CObject::Dump(dc);
  1098.  
  1099.     dc << "m_hObject = " << (UINT)m_hObject;
  1100.     dc << "\n";
  1101. }
  1102.  
  1103. void CGdiObject::AssertValid() const
  1104. {
  1105.     CObject::AssertValid();
  1106.     ASSERT(m_hObject == NULL ||
  1107.         (afxData.bWin95 || ::GetObjectType(m_hObject) != 0));
  1108. }
  1109. #endif
  1110.  
  1111. #if !defined(_WIN32_WCE)
  1112. #include "fixalloc.h"
  1113.  
  1114. class CTempGdiObject : public CGdiObject
  1115. {
  1116.     DECLARE_DYNCREATE(CTempGdiObject)
  1117.     DECLARE_FIXED_ALLOC(CTempGdiObject);
  1118. };
  1119. #endif // _WIN32_WCE
  1120.  
  1121. CHandleMap* PASCAL afxMapHGDIOBJ(BOOL bCreate)
  1122. {
  1123.     AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  1124.     if (pState->m_pmapHGDIOBJ == NULL && bCreate)
  1125.     {
  1126.         BOOL bEnable = AfxEnableMemoryTracking(FALSE);
  1127. #ifndef _AFX_PORTABLE
  1128.         _PNH pnhOldHandler = AfxSetNewHandler(&AfxCriticalNewHandler);
  1129. #endif
  1130.         pState->m_pmapHGDIOBJ = new CHandleMap(WCE_IF(RUNTIME_CLASS(CGdiObject),RUNTIME_CLASS(CTempGdiObject)),
  1131.             offsetof(CGdiObject, m_hObject));
  1132.  
  1133. #ifndef _AFX_PORTABLE
  1134.         AfxSetNewHandler(pnhOldHandler);
  1135. #endif
  1136.         AfxEnableMemoryTracking(bEnable);
  1137.     }
  1138.     return pState->m_pmapHGDIOBJ;
  1139. }
  1140.  
  1141. CGdiObject* PASCAL CGdiObject::FromHandle(HGDIOBJ h)
  1142. {
  1143.     CHandleMap* pMap = afxMapHGDIOBJ(TRUE); //create map if not exist
  1144.     ASSERT(pMap != NULL);
  1145.     CGdiObject* pObject = (CGdiObject*)pMap->FromHandle(h);
  1146.     ASSERT(pObject == NULL || pObject->m_hObject == h);
  1147.     return pObject;
  1148. }
  1149.  
  1150. BOOL CGdiObject::Attach(HGDIOBJ hObject)
  1151. {
  1152.     ASSERT(m_hObject == NULL);      // only attach once, detach on destroy
  1153.     if (hObject == NULL)
  1154.         return FALSE;
  1155.     CHandleMap* pMap = afxMapHGDIOBJ(TRUE); // create map if not exist
  1156.     ASSERT(pMap != NULL);
  1157.     pMap->SetPermanent(m_hObject = hObject, this);
  1158.     return TRUE;
  1159. }
  1160.  
  1161. HGDIOBJ CGdiObject::Detach()
  1162. {
  1163.     HGDIOBJ hObject = m_hObject;
  1164.     if (hObject != NULL)
  1165.     {
  1166.         CHandleMap* pMap = afxMapHGDIOBJ(); // don't create if not exist
  1167.         if (pMap != NULL)
  1168.             pMap->RemoveHandle(m_hObject);
  1169.     }
  1170.  
  1171.     m_hObject = NULL;
  1172.     return hObject;
  1173. }
  1174.  
  1175. BOOL CGdiObject::DeleteObject()
  1176. {
  1177.     if (m_hObject == NULL)
  1178.         return FALSE;
  1179.     return ::DeleteObject(Detach());
  1180. }
  1181.  
  1182. /////////////////////////////////////////////////////////////////////////////
  1183. // Standard GDI objects
  1184.  
  1185. /////////////////////////////////////////////////////////////////////////////
  1186. // CPen
  1187.  
  1188. CPen::CPen(int nPenStyle, int nWidth, COLORREF crColor)
  1189. {
  1190.     if (!Attach(::WCE_FCTN(CreatePen)(nPenStyle, nWidth, crColor)))
  1191.         AfxThrowResourceException();
  1192. }
  1193.  
  1194. #if !defined(_WIN32_WCE)
  1195. CPen::CPen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush,
  1196.     int nStyleCount, const DWORD* lpStyle)
  1197. {
  1198.     if (!Attach(::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount,
  1199.             lpStyle)))
  1200.         AfxThrowResourceException();
  1201. }
  1202. #endif // _WIN32_WCE
  1203.  
  1204. /////////////////////////////////////////////////////////////////////////////
  1205.  
  1206. #ifdef _DEBUG
  1207. void CPen::Dump(CDumpContext& dc) const
  1208. {
  1209.     CGdiObject::Dump(dc);
  1210.  
  1211.     if (m_hObject == NULL)
  1212.         return;
  1213.  
  1214.     if (!afxData.bWin95 && ::GetObjectType(m_hObject) != OBJ_PEN)
  1215.     {
  1216.         // not a valid object
  1217.         dc << "has ILLEGAL HPEN!";
  1218.         return;
  1219.     }
  1220.  
  1221.     LOGPEN lp;
  1222.     VERIFY(GetObject(sizeof(lp), &lp));
  1223.     dc << "lgpn.lopnStyle = " << lp.lopnStyle;
  1224.     dc << "\nlgpn.lopnWidth.x (width) = " << lp.lopnWidth.x;
  1225.     dc << "\nlgpn.lopnColor = " << (void*)lp.lopnColor;
  1226.  
  1227.     dc << "\n";
  1228. }
  1229. #endif
  1230.  
  1231. /////////////////////////////////////////////////////////////////////////////
  1232. // CBrush
  1233.  
  1234. CBrush::CBrush(COLORREF crColor)
  1235. {
  1236.     if (!Attach(::CreateSolidBrush(crColor)))
  1237.         AfxThrowResourceException();
  1238. }
  1239.  
  1240. #if !defined(_WIN32_WCE)
  1241. CBrush::CBrush(int nIndex, COLORREF crColor)
  1242. {
  1243.     if (!Attach(::CreateHatchBrush(nIndex, crColor)))
  1244.         AfxThrowResourceException();
  1245. }
  1246. #endif // _WIN32_WCE
  1247.  
  1248. CBrush::CBrush(CBitmap* pBitmap)
  1249. {
  1250.     ASSERT_VALID(pBitmap);
  1251.  
  1252.     if (!Attach(::CreatePatternBrush((HBITMAP)pBitmap->m_hObject)))
  1253.         AfxThrowResourceException();
  1254. }
  1255.  
  1256. BOOL CBrush::CreateDIBPatternBrush(HGLOBAL hPackedDIB, UINT nUsage)
  1257. {
  1258.     ASSERT(hPackedDIB != NULL);
  1259.     const void* lpPackedDIB = ::WCE_FCTN(GlobalLock)(hPackedDIB);
  1260.     ASSERT(lpPackedDIB != NULL);
  1261.     BOOL bResult = Attach(::CreateDIBPatternBrushPt(lpPackedDIB, nUsage));
  1262.     ::WCE_FCTN(GlobalUnlock)(hPackedDIB);
  1263.     return bResult;
  1264. }
  1265.  
  1266. #ifdef _DEBUG
  1267. void CBrush::Dump(CDumpContext& dc) const
  1268. {
  1269.     CGdiObject::Dump(dc);
  1270.  
  1271.     if (m_hObject == NULL)
  1272.         return;
  1273.  
  1274.     if (!afxData.bWin95 && ::GetObjectType(m_hObject) != OBJ_BRUSH)
  1275.     {
  1276.         // not a valid window
  1277.         dc << "has ILLEGAL HBRUSH!";
  1278.         return;
  1279.     }
  1280.  
  1281.     LOGBRUSH lb;
  1282.     VERIFY(GetObject(sizeof(lb), &lb));
  1283.     dc << "lb.lbStyle = " << lb.lbStyle;
  1284.     dc << "\nlb.lbHatch = " << lb.lbHatch;
  1285.     dc << "\nlb.lbColor = " << (void*)lb.lbColor;
  1286.  
  1287.     dc << "\n";
  1288. }
  1289. #endif
  1290.  
  1291. /////////////////////////////////////////////////////////////////////////////
  1292.  
  1293. #ifdef _DEBUG
  1294. void CFont::Dump(CDumpContext& dc) const
  1295. {
  1296.     CGdiObject::Dump(dc);
  1297.  
  1298.     if (m_hObject == NULL)
  1299.         return;
  1300.  
  1301.     if (!afxData.bWin95 && ::GetObjectType(m_hObject) != OBJ_FONT)
  1302.     {
  1303.         // not a valid GDI object
  1304.         dc << "has ILLEGAL HFONT!";
  1305.         return;
  1306.     }
  1307.  
  1308.     LOGFONT lf;
  1309.     VERIFY(GetObject(sizeof(lf), &lf));
  1310.     dc << "lf.lfHeight = " << lf.lfHeight;
  1311.     dc << "\nlf.lfWidth = " << lf.lfWidth;
  1312.     dc << "\nlf.lfEscapement = " << lf.lfEscapement;
  1313.     dc << "\nlf.lfOrientation = " << lf.lfOrientation;
  1314.     dc << "\nlf.lfWeight = " << lf.lfWeight;
  1315.     dc << "\nlf.lfItalic = " << (int)lf.lfItalic;
  1316.     dc << "\nlf.lfUnderline = " << (int)lf.lfUnderline;
  1317.     dc << "\nlf.lfStrikeOut = " << (int)lf.lfStrikeOut;
  1318.     dc << "\nlf.lfCharSet = " << (int)lf.lfCharSet;
  1319.     dc << "\nlf.lfOutPrecision = " << (int)lf.lfOutPrecision;
  1320.     dc << "\nlf.lfClipPrecision = " << (int)lf.lfClipPrecision;
  1321.     dc << "\nlf.lfQuality = " << (int)lf.lfQuality;
  1322.     dc << "\nlf.lfPitchAndFamily = " << (int)lf.lfPitchAndFamily;
  1323.     dc << "\nlf.lfFaceName = " << (LPCTSTR)lf.lfFaceName;
  1324.  
  1325.     dc << "\n";
  1326. }
  1327. #endif
  1328.  
  1329. /////////////////////////////////////////////////////////////////////////////
  1330.  
  1331. #ifdef _DEBUG
  1332. void CBitmap::Dump(CDumpContext& dc) const
  1333. {
  1334.     CGdiObject::Dump(dc);
  1335.  
  1336.     if (m_hObject == NULL)
  1337.         return;
  1338.  
  1339.     if (!afxData.bWin95 && ::GetObjectType(m_hObject) != OBJ_BITMAP)
  1340.     {
  1341.         // not a valid object
  1342.         dc << "has ILLEGAL HBITMAP!";
  1343.         return;
  1344.     }
  1345.  
  1346.     BITMAP bm;
  1347.     VERIFY(GetObject(sizeof(bm), &bm));
  1348.     dc << "bm.bmType = " << bm.bmType;
  1349.     dc << "\nbm.bmHeight = " << bm.bmHeight;
  1350.     dc << "\nbm.bmWidth = " << bm.bmWidth;
  1351.     dc << "\nbm.bmWidthBytes = " << bm.bmWidthBytes;
  1352.     dc << "\nbm.bmPlanes = " << bm.bmPlanes;
  1353.     dc << "\nbm.bmBitsPixel = " << bm.bmBitsPixel;
  1354.  
  1355.     dc << "\n";
  1356. }
  1357. #endif
  1358.  
  1359. #ifdef AFX_INIT_SEG
  1360. #pragma code_seg(AFX_INIT_SEG)
  1361. #endif
  1362.  
  1363. IMPLEMENT_DYNAMIC(CResourceException, CException)
  1364. CResourceException _simpleResourceException(FALSE, AFX_IDS_RESOURCE_EXCEPTION);
  1365.  
  1366. IMPLEMENT_DYNAMIC(CUserException, CException)
  1367. CUserException _simpleUserException(FALSE, AFX_IDS_USER_EXCEPTION);
  1368.  
  1369. IMPLEMENT_DYNCREATE(CDC, CObject)
  1370. IMPLEMENT_DYNAMIC(CClientDC, CDC)
  1371. IMPLEMENT_DYNAMIC(CWindowDC, CDC)
  1372. IMPLEMENT_DYNAMIC(CPaintDC, CDC)
  1373. IMPLEMENT_DYNCREATE(CGdiObject, CObject)
  1374.  
  1375. IMPLEMENT_DYNAMIC(CPen, CGdiObject)
  1376. IMPLEMENT_DYNAMIC(CBrush, CGdiObject)
  1377. IMPLEMENT_DYNAMIC(CFont, CGdiObject)
  1378. IMPLEMENT_DYNAMIC(CBitmap, CGdiObject)
  1379. IMPLEMENT_DYNAMIC(CPalette, CGdiObject)
  1380. IMPLEMENT_DYNAMIC(CRgn, CGdiObject)
  1381.  
  1382. #if !defined(_WIN32_WCE)
  1383. IMPLEMENT_DYNCREATE(CTempDC, CDC);
  1384.  
  1385. IMPLEMENT_DYNCREATE(CTempGdiObject, CGdiObject);
  1386. #endif // _WIN32_WCE
  1387.  
  1388. /////////////////////////////////////////////////////////////////////////////
  1389. // Standard exception processing
  1390.  
  1391. #ifdef AFX_CORE2_SEG
  1392. #pragma code_seg(AFX_CORE2_SEG)
  1393. #endif
  1394.  
  1395. // resource failure
  1396. void AFXAPI AfxThrowResourceException()
  1397. {
  1398.     THROW((CResourceException*)&_simpleResourceException);
  1399. }
  1400.  
  1401. // user alert
  1402. void AFXAPI AfxThrowUserException()
  1403. {
  1404.     THROW((CUserException*)&_simpleUserException);
  1405. }
  1406.  
  1407. #ifdef AFX_INIT_SEG
  1408. #pragma code_seg(AFX_INIT_SEG)
  1409. #endif
  1410.  
  1411. #if !defined(_WIN32_WCE)
  1412. #pragma warning(disable: 4074)
  1413. #pragma init_seg(compiler)
  1414. IMPLEMENT_FIXED_ALLOC(CTempDC, 64);
  1415. IMPLEMENT_FIXED_ALLOC(CTempGdiObject, 64);
  1416. #endif // _WIN32_WCE
  1417.  
  1418. /////////////////////////////////////////////////////////////////////////////
  1419.