home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / wingdix.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  10.2 KB  |  385 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_CORE4_SEG
  14. #pragma code_seg(AFX_CORE4_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. AFX_STATIC_DATA HBRUSH _afxHalftoneBrush = 0;
  23.  
  24. void AFX_CDECL AfxWingdixTerm()
  25. {
  26.     AfxDeleteObject((HGDIOBJ*)&_afxHalftoneBrush);
  27. }
  28. char _afxWingdixTerm = (char)atexit(&AfxWingdixTerm);
  29.  
  30. /////////////////////////////////////////////////////////////////////////////
  31. // More coordinate transforms (in separate file to avoid transitive refs)
  32.  
  33. #if defined(_WIN32_WCE) 
  34. void CDC::LPtoHIMETRIC(LPSIZE lpSize) const
  35. {
  36.     DPtoHIMETRIC(lpSize);    // because of MM_TEXT assumption
  37. }
  38.  
  39. void CDC::DPtoHIMETRIC(LPSIZE lpSize) const
  40. {
  41.     double lfLogX = GetDeviceCaps(LOGPIXELSX); // pts/in
  42.     double lfLogY = GetDeviceCaps(LOGPIXELSY); // pts/in
  43.  
  44.     // convert:        pts          in       cm     .01mm
  45.     lpSize->cx = (int)(lpSize->cx / lfLogX * 2.54 * 1000.0);  
  46.     lpSize->cy = (int)(lpSize->cy / lfLogY * 2.54 * 1000.0);  
  47. }
  48.  
  49. void CDC::HIMETRICtoLP(LPSIZE lpSize) const
  50. {
  51.     HIMETRICtoDP(lpSize);    // because of MM_TEXT assumption
  52. }
  53.  
  54. void CDC::HIMETRICtoDP(LPSIZE lpSize) const
  55. {
  56.     double lfLogX = GetDeviceCaps(LOGPIXELSX); // pts/in
  57.     double lfLogY = GetDeviceCaps(LOGPIXELSY); // pts/in
  58.  
  59.     // convert:        .01mm        cm     in     pts
  60.     lpSize->cx = (int)(lpSize->cx / 1000.0 * lfLogX / 2.54 );  
  61.     lpSize->cy = (int)(lpSize->cy / 1000.0 * lfLogY / 2.54 );   
  62. }
  63. #else // _WIN32_WCE
  64. #define HIMETRIC_INCH   2540    // HIMETRIC units per inch
  65.  
  66. void CDC::DPtoHIMETRIC(LPSIZE lpSize) const
  67. {
  68.     ASSERT(AfxIsValidAddress(lpSize, sizeof(SIZE)));
  69.  
  70.     int nMapMode;
  71.     if (this != NULL && (nMapMode = GetMapMode()) < MM_ISOTROPIC &&
  72.         nMapMode != MM_TEXT)
  73.     {
  74.         // when using a constrained map mode, map against physical inch
  75.         ((CDC*)this)->SetMapMode(MM_HIMETRIC);
  76.         DPtoLP(lpSize);
  77.         ((CDC*)this)->SetMapMode(nMapMode);
  78.     }
  79.     else
  80.     {
  81.         // map against logical inch for non-constrained mapping modes
  82.         int cxPerInch, cyPerInch;
  83.         if (this != NULL)
  84.         {
  85.             ASSERT_VALID(this);
  86.             ASSERT(m_hDC != NULL);  // no HDC attached or created?
  87.             cxPerInch = GetDeviceCaps(LOGPIXELSX);
  88.             cyPerInch = GetDeviceCaps(LOGPIXELSY);
  89.         }
  90.         else
  91.         {
  92.             cxPerInch = afxData.cxPixelsPerInch;
  93.             cyPerInch = afxData.cyPixelsPerInch;
  94.         }
  95.         ASSERT(cxPerInch != 0 && cyPerInch != 0);
  96.         lpSize->cx = MulDiv(lpSize->cx, HIMETRIC_INCH, cxPerInch);
  97.         lpSize->cy = MulDiv(lpSize->cy, HIMETRIC_INCH, cyPerInch);
  98.     }
  99. }
  100.  
  101. void CDC::HIMETRICtoDP(LPSIZE lpSize) const
  102. {
  103.     ASSERT(AfxIsValidAddress(lpSize, sizeof(SIZE)));
  104.  
  105.     int nMapMode;
  106.     if (this != NULL && (nMapMode = GetMapMode()) < MM_ISOTROPIC &&
  107.         nMapMode != MM_TEXT)
  108.     {
  109.         // when using a constrained map mode, map against physical inch
  110.         ((CDC*)this)->SetMapMode(MM_HIMETRIC);
  111.         LPtoDP(lpSize);
  112.         ((CDC*)this)->SetMapMode(nMapMode);
  113.     }
  114.     else
  115.     {
  116.         // map against logical inch for non-constrained mapping modes
  117.         int cxPerInch, cyPerInch;
  118.         if (this != NULL)
  119.         {
  120.             ASSERT_VALID(this);
  121.             ASSERT(m_hDC != NULL);  // no HDC attached or created?
  122.             cxPerInch = GetDeviceCaps(LOGPIXELSX);
  123.             cyPerInch = GetDeviceCaps(LOGPIXELSY);
  124.         }
  125.         else
  126.         {
  127.             cxPerInch = afxData.cxPixelsPerInch;
  128.             cyPerInch = afxData.cyPixelsPerInch;
  129.         }
  130.         ASSERT(cxPerInch != 0 && cyPerInch != 0);
  131.         lpSize->cx = MulDiv(lpSize->cx, cxPerInch, HIMETRIC_INCH);
  132.         lpSize->cy = MulDiv(lpSize->cy, cyPerInch, HIMETRIC_INCH);
  133.     }
  134. }
  135.  
  136. void CDC::LPtoHIMETRIC(LPSIZE lpSize) const
  137. {
  138.     ASSERT(AfxIsValidAddress(lpSize, sizeof(SIZE)));
  139.  
  140.     LPtoDP(lpSize);
  141.     DPtoHIMETRIC(lpSize);
  142. }
  143.  
  144. void CDC::HIMETRICtoLP(LPSIZE lpSize) const
  145. {
  146.     ASSERT(AfxIsValidAddress(lpSize, sizeof(SIZE)));
  147.  
  148.     HIMETRICtoDP(lpSize);
  149.     DPtoLP(lpSize);
  150. }
  151. #endif // _WIN32_WCE
  152.  
  153. /////////////////////////////////////////////////////////////////////////////
  154. // special CDC drawing primitives/helpers
  155.  
  156. CBrush* PASCAL CDC::GetHalftoneBrush()
  157. {
  158.     AfxLockGlobals(CRIT_HALFTONEBRUSH);
  159.     if (_afxHalftoneBrush == NULL)
  160.     {
  161.         WORD grayPattern[8];
  162.         for (int i = 0; i < 8; i++)
  163.             grayPattern[i] = (WORD)(0x5555 << (i & 1));
  164.         HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern);
  165.         if (grayBitmap != NULL)
  166.         {
  167.             _afxHalftoneBrush = ::CreatePatternBrush(grayBitmap);
  168.             DeleteObject(grayBitmap);
  169.         }
  170.     }
  171.     AfxUnlockGlobals(CRIT_HALFTONEBRUSH);
  172.     return CBrush::FromHandle(_afxHalftoneBrush);
  173. }
  174.  
  175. void CDC::DrawDragRect(LPCRECT lpRect, SIZE size,
  176.     LPCRECT lpRectLast, SIZE sizeLast, CBrush* pBrush, CBrush* pBrushLast)
  177. {
  178.     ASSERT(AfxIsValidAddress(lpRect, sizeof(RECT), FALSE));
  179.     ASSERT(lpRectLast == NULL ||
  180.         AfxIsValidAddress(lpRectLast, sizeof(RECT), FALSE));
  181.  
  182.     // first, determine the update region and select it
  183.     CRgn rgnNew;
  184.     CRgn rgnOutside, rgnInside;
  185.     rgnOutside.CreateRectRgnIndirect(lpRect);
  186.     CRect rect = *lpRect;
  187.     rect.InflateRect(-size.cx, -size.cy);
  188.     rect.IntersectRect(rect, lpRect);
  189.     rgnInside.CreateRectRgnIndirect(rect);
  190.     rgnNew.CreateRectRgn(0, 0, 0, 0);
  191.     rgnNew.CombineRgn(&rgnOutside, &rgnInside, RGN_XOR);
  192.  
  193.     CBrush* pBrushOld = NULL;
  194.     if (pBrush == NULL)
  195.         pBrush = CDC::GetHalftoneBrush();
  196.     if (pBrushLast == NULL)
  197.         pBrushLast = pBrush;
  198.  
  199.     CRgn rgnLast, rgnUpdate;
  200.     if (lpRectLast != NULL)
  201.     {
  202.         // find difference between new region and old region
  203.         rgnLast.CreateRectRgn(0, 0, 0, 0);
  204.         rgnOutside.SetRectRgn(lpRectLast);
  205.         rect = *lpRectLast;
  206.         rect.InflateRect(-sizeLast.cx, -sizeLast.cy);
  207.         rect.IntersectRect(rect, lpRectLast);
  208.         rgnInside.SetRectRgn(rect);
  209.         rgnLast.CombineRgn(&rgnOutside, &rgnInside, RGN_XOR);
  210.  
  211.         // only diff them if brushes are the same
  212.         if (pBrush->m_hObject == pBrushLast->m_hObject)
  213.         {
  214.             rgnUpdate.CreateRectRgn(0, 0, 0, 0);
  215.             rgnUpdate.CombineRgn(&rgnLast, &rgnNew, RGN_XOR);
  216.         }
  217.     }
  218.     if (pBrush->m_hObject != pBrushLast->m_hObject && lpRectLast != NULL)
  219.     {
  220.         // brushes are different -- erase old region first
  221.         SelectClipRgn(&rgnLast);
  222.         GetClipBox(&rect);
  223.         pBrushOld = SelectObject(pBrushLast);
  224.         PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
  225.         SelectObject(pBrushOld);
  226.         pBrushOld = NULL;
  227.     }
  228.  
  229.     // draw into the update/new region
  230.     SelectClipRgn(rgnUpdate.m_hObject != NULL ? &rgnUpdate : &rgnNew);
  231.     GetClipBox(&rect);
  232.     pBrushOld = SelectObject(pBrush);
  233.     PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
  234.  
  235.     // cleanup DC
  236.     if (pBrushOld != NULL)
  237.         SelectObject(pBrushOld);
  238.     SelectClipRgn(NULL);
  239. }
  240.  
  241. void CDC::FillSolidRect(LPCRECT lpRect, COLORREF clr)
  242. {
  243.     ASSERT_VALID(this);
  244.     ASSERT(m_hDC != NULL);
  245.  
  246.     ::SetBkColor(m_hDC, clr);
  247.     ::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL);
  248. }
  249.  
  250. void CDC::FillSolidRect(int x, int y, int cx, int cy, COLORREF clr)
  251. {
  252.     ASSERT_VALID(this);
  253.     ASSERT(m_hDC != NULL);
  254.  
  255.     ::SetBkColor(m_hDC, clr);
  256.     CRect rect(x, y, x + cx, y + cy);
  257.     ::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
  258. }
  259.  
  260. void CDC::Draw3dRect(LPCRECT lpRect,
  261.     COLORREF clrTopLeft, COLORREF clrBottomRight)
  262. {
  263.     Draw3dRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left,
  264.         lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight);
  265. }
  266.  
  267. void CDC::Draw3dRect(int x, int y, int cx, int cy,
  268.     COLORREF clrTopLeft, COLORREF clrBottomRight)
  269. {
  270.     FillSolidRect(x, y, cx - 1, 1, clrTopLeft);
  271.     FillSolidRect(x, y, 1, cy - 1, clrTopLeft);
  272.     FillSolidRect(x + cx, y, -1, cy, clrBottomRight);
  273.     FillSolidRect(x, y + cy, cx, -1, clrBottomRight);
  274. }
  275.  
  276. /////////////////////////////////////////////////////////////////////////////
  277. // out-of-line CBrush, CFont, etc. helpers
  278.  
  279. // nPointSize is actually scaled 10x
  280. BOOL CFont::CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, CDC* pDC)
  281. {
  282.     ASSERT(AfxIsValidString(lpszFaceName));
  283.  
  284.     LOGFONT logFont;
  285.     memset(&logFont, 0, sizeof(LOGFONT));
  286.     logFont.lfCharSet = DEFAULT_CHARSET;
  287.     logFont.lfHeight = nPointSize;
  288.     lstrcpyn(logFont.lfFaceName, lpszFaceName, _countof(logFont.lfFaceName));
  289.  
  290.     return CreatePointFontIndirect(&logFont, pDC);
  291. }
  292.  
  293. // pLogFont->nHeight is interpreted as PointSize * 10
  294. BOOL CFont::CreatePointFontIndirect(const LOGFONT* lpLogFont, CDC* pDC)
  295. {
  296.     ASSERT(AfxIsValidAddress(lpLogFont, sizeof(LOGFONT), FALSE));
  297.     HDC hDC;
  298.     if (pDC != NULL)
  299.     {
  300.         ASSERT_VALID(pDC);
  301.         ASSERT(pDC->m_hAttribDC != NULL);
  302.         hDC = pDC->m_hAttribDC;
  303.     }
  304.     else
  305.         hDC = ::GetDC(NULL);
  306.  
  307.     // convert nPointSize to logical units based on pDC
  308.     LOGFONT logFont = *lpLogFont;
  309.     POINT pt;
  310.     pt.y = ::GetDeviceCaps(hDC, LOGPIXELSY) * logFont.lfHeight;
  311.     pt.y /= 720;    // 72 points/inch, 10 decipoints/point
  312.     ::WCE_FCTN(DPtoLP)(hDC, &pt, 1);
  313.     POINT ptOrg = { 0, 0 };
  314.     ::WCE_FCTN(DPtoLP)(hDC, &ptOrg, 1);
  315.     logFont.lfHeight = -abs(pt.y - ptOrg.y);
  316.  
  317.     if (pDC == NULL)
  318.         ReleaseDC(NULL, hDC);
  319.  
  320.     return CreateFontIndirect(&logFont);
  321. }
  322.  
  323. /////////////////////////////////////////////////////////////////////////////
  324. // out-of-line CRect, CSize, etc. helpers
  325.  
  326. void CRect::NormalizeRect()
  327. {
  328.     int nTemp;
  329.     if (left > right)
  330.     {
  331.         nTemp = left;
  332.         left = right;
  333.         right = nTemp;
  334.     }
  335.     if (top > bottom)
  336.     {
  337.         nTemp = top;
  338.         top = bottom;
  339.         bottom = nTemp;
  340.     }
  341. }
  342.  
  343. void CRect::InflateRect(LPCRECT lpRect)
  344. {
  345.     left -= lpRect->left;
  346.     top -= lpRect->top;
  347.     right += lpRect->right;
  348.     bottom += lpRect->bottom;
  349. }
  350.  
  351. void CRect::InflateRect(int l, int t, int r, int b)
  352. {
  353.     left -= l;
  354.     top -= t;
  355.     right += r;
  356.     bottom += b;
  357. }
  358.  
  359. void CRect::DeflateRect(LPCRECT lpRect)
  360. {
  361.     left += lpRect->left;
  362.     top += lpRect->top;
  363.     right -= lpRect->right;
  364.     bottom -= lpRect->bottom;
  365. }
  366.  
  367. void CRect::DeflateRect(int l, int t, int r, int b)
  368. {
  369.     left += l;
  370.     top += t;
  371.     right -= r;
  372.     bottom -= b;
  373. }
  374.  
  375. CRect CRect::MulDiv(int nMultiplier, int nDivisor) const
  376. {
  377.     return CRect(
  378.         ::WCE_FCTN(MulDiv)(left, nMultiplier, nDivisor),
  379.         ::WCE_FCTN(MulDiv)(top, nMultiplier, nDivisor),
  380.         ::WCE_FCTN(MulDiv)(right, nMultiplier, nDivisor),
  381.         ::WCE_FCTN(MulDiv)(bottom, nMultiplier, nDivisor));
  382. }
  383.  
  384. /////////////////////////////////////////////////////////////////////////////
  385.