home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 19.ddi / MFC / SRC / DCMETA.CP_ / DCMETA.CP
Encoding:
Text File  |  1993-02-08  |  6.6 KB  |  271 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.  
  14. #ifdef AFX_PRINT_SEG
  15. #pragma code_seg(AFX_PRINT_SEG)
  16. #endif
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char BASED_CODE THIS_FILE[] = __FILE__;
  21. #define new DEBUG_NEW
  22. #endif
  23.  
  24. IMPLEMENT_DYNAMIC(CMetaFileDC, CDC)
  25.  
  26. CMetaFileDC::CMetaFileDC()
  27. {
  28. }
  29.  
  30. BOOL CMetaFileDC::Create(LPCSTR lpszFilename)
  31. {
  32.     return Attach(::CreateMetaFile(lpszFilename));
  33. }
  34.  
  35. // Special close
  36. HMETAFILE CMetaFileDC::Close()
  37. {
  38.     return ::CloseMetaFile(Detach());
  39. }
  40.  
  41. void CMetaFileDC::SetOutputDC(HDC)
  42. {
  43.     TRACE0("Must use Create() or Get() to set Metafile Output DC\n");
  44.     ASSERT(FALSE);
  45. }
  46. void CMetaFileDC::ReleaseOutputDC()
  47. {
  48.     TRACE0("Must use Close() to release output Metafile DC\n");
  49.     ASSERT(FALSE);
  50. }
  51.  
  52. void CMetaFileDC::SetAttribDC(HDC hDC)  // Set the Attribute DC
  53. {
  54.     if (hDC != m_hDC)
  55.         CDC::SetAttribDC(hDC);
  56.     if (m_hDC == m_hAttribDC)   // if we somehow got to this, correct it
  57.         ReleaseAttribDC();
  58. }
  59.  
  60. CMetaFileDC::~CMetaFileDC()
  61. {
  62.     if (m_hDC != NULL)      // Must be not wanting to keep the metafile
  63.     {
  64.         TRACE0("Warning!  Destroying CMetaFileDC without closing\n");
  65.         HMETAFILE hmfTemp = Close();
  66.         ::DeleteMetaFile(hmfTemp);
  67.     }
  68. }
  69.  
  70.  
  71. // Implementation
  72. #ifdef _DEBUG
  73. void CMetaFileDC::AssertValid() const
  74. {
  75.     CDC::AssertValid();
  76. }
  77.  
  78. void CMetaFileDC::Dump(CDumpContext& dc) const
  79. {
  80.     CDC::Dump(dc);
  81. }
  82.  
  83. #endif
  84.  
  85. // Device-Context Functions
  86.  
  87.  
  88. // Clipping Functions
  89. // Normally both Set and Get clipping functions go directly to the output DC
  90. // With metafiles, we must mirror to both DCs and ask the Attribute DC for
  91. // the Get.
  92.  
  93. int CMetaFileDC::GetClipBox(LPRECT lpRect) const
  94. {
  95.     ASSERT(m_hAttribDC != NULL);
  96.     ASSERT(lpRect != NULL);
  97.     ASSERT(AfxIsValidAddress(lpRect, sizeof(RECT)));
  98.  
  99.     return ::GetClipBox(m_hAttribDC, lpRect);
  100. }
  101.  
  102. BOOL CMetaFileDC::PtVisible(int x, int y) const
  103. {
  104.     ASSERT(m_hAttribDC != NULL);
  105.     return ::PtVisible(m_hAttribDC, x, y);
  106. }
  107.  
  108. BOOL CMetaFileDC::RectVisible(LPRECT lpRect) const
  109. {
  110.     ASSERT(m_hAttribDC != NULL);
  111.     ASSERT(lpRect != NULL);
  112.     ASSERT(AfxIsValidAddress(lpRect, sizeof(RECT)));
  113.  
  114.     return ::RectVisible(m_hAttribDC, lpRect);
  115. }
  116.  
  117.  
  118. // Text Functions
  119. BOOL CMetaFileDC::TextOut(int x, int y, LPCSTR lpszString, int nCount)
  120. {
  121.     ASSERT(m_hDC != NULL);
  122.     ASSERT(m_hDC != m_hAttribDC);
  123.     ASSERT(lpszString != NULL);
  124.     ASSERT(AfxIsValidAddress(lpszString, nCount));
  125.  
  126.     BOOL bSuccess = ::TextOut(m_hDC, x, y, lpszString, nCount);
  127.     if (bSuccess && m_hAttribDC != NULL && (GetTextAlign() & TA_UPDATECP))
  128.     {
  129.         CSize size = GetTextExtent(lpszString, nCount);
  130.         TEXTMETRIC tm;
  131.         GetTextMetrics(&tm);
  132.         AdjustCP(size.cx - tm.tmOverhang);
  133.     }
  134.     return bSuccess;
  135. }
  136.  
  137. BOOL CMetaFileDC::ExtTextOut(int x, int y, UINT nOptions, LPRECT lpRect,
  138.               LPCSTR lpszString, UINT nCount, LPINT lpDxWidths)
  139. {
  140.     ASSERT(m_hDC != NULL);
  141.     ASSERT(m_hDC != m_hAttribDC);
  142.     ASSERT(lpszString != NULL);
  143.     ASSERT(lpDxWidths == NULL ||
  144.             AfxIsValidAddress(lpDxWidths, sizeof(int) * nCount, FALSE));
  145.     ASSERT(AfxIsValidAddress(lpszString, nCount));
  146.  
  147.     BOOL bSuccess = ::ExtTextOut(m_hDC, x, y, nOptions, lpRect,
  148.               lpszString, nCount, lpDxWidths);
  149.  
  150.     if (bSuccess && m_hAttribDC != NULL && (GetTextAlign() & TA_UPDATECP))
  151.     {
  152.         int nWidth = 0;
  153.         for (UINT i = 0; i < nCount; i++)
  154.             nWidth += *lpDxWidths++;
  155.         AdjustCP(nWidth);
  156.     }
  157.     return bSuccess;
  158. }
  159.  
  160. CSize CMetaFileDC::TabbedTextOut(int, int, LPCSTR, int, int, LPINT, int)
  161. {
  162.     ASSERT(FALSE);      // Invalid for Metafile
  163.     return 0;
  164. }
  165.  
  166. void CMetaFileDC::AdjustCP(int cx)
  167. {
  168.     if (m_hAttribDC == NULL)
  169.         return;     // do nothing
  170.     UINT nAlign = GetTextAlign() & (TA_LEFT|TA_CENTER|TA_RIGHT);
  171.     if (nAlign == TA_CENTER)
  172.         return;     // Center Alignment does not affect CP
  173.     if (nAlign == TA_RIGHT)
  174.         cx = -cx;
  175.  
  176.     CPoint point = GetCurrentPosition();
  177.     point.x += cx;
  178.     ::MoveTo(m_hAttribDC, point.x, point.y);
  179. }
  180.  
  181. int CMetaFileDC::DrawText(LPCSTR lpszString, int nCount, LPRECT lpRect,
  182.                     UINT nFormat)
  183. {
  184.     ASSERT(m_hDC != NULL);
  185.     ASSERT(m_hDC != m_hAttribDC);
  186.     ASSERT(lpszString != NULL);
  187.     ASSERT(lpRect != NULL);
  188.     ASSERT(AfxIsValidAddress(lpRect, sizeof(RECT)));
  189.     ASSERT(nCount == -1 || AfxIsValidAddress(lpszString, nCount, FALSE));
  190.  
  191.     ::DrawText(m_hDC, lpszString, nCount, lpRect, nFormat);
  192.     int nHeight = 0;
  193.  
  194.     // If adjusting CP:
  195.     if (m_hAttribDC != NULL &&
  196.         (GetTextAlign() & TA_UPDATECP) && ((nFormat & DT_CALCRECT) == 0))
  197.     {
  198.         CRect rect(lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
  199.         nHeight = ::DrawText(m_hAttribDC, lpszString, nCount, &rect,
  200.             nFormat | DT_CALCRECT | DT_SINGLELINE);
  201.         AdjustCP(rect.Width());
  202.     }
  203.  
  204.     return nHeight;
  205. }
  206.  
  207. // Printer Escape Functions
  208. int CMetaFileDC::Escape(int nEscape, int nCount, LPCSTR lpszInData, LPVOID lpOutData)
  209. {
  210.     ASSERT(m_hDC != NULL);
  211.     ASSERT(m_hDC != m_hAttribDC);
  212.     int nRet = ::Escape(m_hDC, nEscape, nCount, lpszInData, lpOutData);
  213.  
  214.     if (m_hAttribDC == NULL)
  215.         return nRet;
  216.  
  217.     // The tact here is to NOT allow any of the document control escapes
  218.     // to be passed through.  Elimination of StartDoc and EndDoc should
  219.     // eliminate anything actually going to the printer.  Also anything
  220.     // that actually draws something will be filtered.
  221.     //
  222.  
  223.     switch (nEscape)
  224.     {
  225.     case NEXTBAND:
  226.     case SETCOLORTABLE:
  227.     case GETCOLORTABLE:
  228.     case FLUSHOUTPUT:
  229.     case DRAFTMODE:
  230.     case QUERYESCSUPPORT:
  231.     case GETPHYSPAGESIZE:
  232.     case GETPRINTINGOFFSET:
  233.     case GETSCALINGFACTOR:
  234.     case GETPENWIDTH:
  235.     case SETCOPYCOUNT:
  236.     case SELECTPAPERSOURCE:
  237.     case GETTECHNOLOGY:
  238.     case SETLINECAP:
  239.     case SETLINEJOIN:
  240.     case SETMITERLIMIT:
  241.     case BANDINFO:
  242.     case GETVECTORPENSIZE:
  243.     case GETVECTORBRUSHSIZE:
  244.     case ENABLEDUPLEX:
  245.     case GETSETPAPERBINS:
  246.     case GETSETPRINTORIENT:
  247.     case ENUMPAPERBINS:
  248.     case SETDIBSCALING:
  249.     case ENUMPAPERMETRICS:
  250.     case GETSETPAPERMETRICS:
  251.     case GETEXTENDEDTEXTMETRICS:
  252.     case GETEXTENTTABLE:
  253.     case GETPAIRKERNTABLE:
  254.     case GETTRACKKERNTABLE:
  255.     case ENABLERELATIVEWIDTHS:
  256.     case ENABLEPAIRKERNING:
  257.     case SETKERNTRACK:
  258.     case SETALLJUSTVALUES:
  259.     case SETCHARSET:
  260.     case SET_BACKGROUND_COLOR:
  261.     case SET_SCREEN_ANGLE:
  262.     case SET_SPREAD:
  263.         return ::Escape(m_hAttribDC, nEscape, nCount, lpszInData, lpOutData);
  264.  
  265.     default:
  266.         break;      // return output DC return value
  267.     }
  268.  
  269.     return nRet;
  270. }
  271.