home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / general / saver / drawwnd.cpp next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  5.7 KB  |  258 lines

  1. // drawwnd.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "Saver.h"
  6. #include "drawwnd.h"
  7.  
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char BASED_CODE THIS_FILE[] = __FILE__;
  11. #endif
  12.  
  13. LPCTSTR CDrawWnd::m_lpszClassName = NULL;
  14.  
  15. int letterM[][3] =
  16. {
  17.     {0,0,0}, {0,8,1}, {3,5,1}, {6,8,1}, {6,0,1}
  18. };
  19.  
  20. int letterC1[][3] =
  21. {
  22.     {6,0,0}, {0,0,1}, {0,4,1}, {0,8,1}, {6,8,1}
  23. };
  24.  
  25. int letterF[][3] =
  26. {
  27.     {0,0,0}, {0,8,1}, {6,8,1}, {0,4,0}, {2,4,1}, {4,4,1}
  28. };
  29.  
  30. int letterPlus[][3] =
  31. {
  32.     {3,0,0}, {3,4,1}, {3,8,1}, {0,4,0}, {3,4,1}, {6,4,1}
  33. };
  34.  
  35. int letterC2[][3] =
  36. {
  37.     {6,0,0}, {0,0,1}, {0,4,1}, {0,4,0}, {0,8,1}, {6,8,1}
  38. };
  39.  
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CDrawWnd
  42.  
  43. CDrawWnd::CDrawWnd(BOOL bAutoDelete)
  44. {
  45.     m_bAutoDelete = bAutoDelete;
  46.     m_nPos = 0;
  47.     m_nStep = 1;
  48.     m_rgnLast.CreateRectRgn(0,0,0,0);
  49.  
  50.     m_nWidth = AfxGetApp()->GetProfileInt("Config", "Width", 10);
  51.     m_nSteps = AfxGetApp()->GetProfileInt("Config", "Resolution", 10);
  52.     m_nStyle = AfxGetApp()->GetProfileInt("Config", "Style", PS_ENDCAP_ROUND|PS_JOIN_ROUND);
  53.     if (m_nSteps < 1)
  54.         m_nSteps = 1;
  55.     m_logbrush.lbStyle = m_logbrushBlack.lbStyle = BS_SOLID;
  56.     m_logbrush.lbHatch = m_logbrushBlack.lbHatch = 0;
  57.     m_logbrush.lbColor = RGB(
  58.         AfxGetApp()->GetProfileInt("Config", "ColorRed", 255),
  59.         AfxGetApp()->GetProfileInt("Config", "ColorGreen", 0),
  60.         AfxGetApp()->GetProfileInt("Config", "ColorBlue", 0));
  61.     m_logbrushBlack.lbColor = RGB(0, 0, 0);
  62. }
  63.  
  64. CDrawWnd::~CDrawWnd()
  65. {
  66. }
  67.  
  68.  
  69. BEGIN_MESSAGE_MAP(CDrawWnd, CWnd)
  70.     //{{AFX_MSG_MAP(CDrawWnd)
  71.     ON_WM_TIMER()
  72.     ON_WM_PAINT()
  73.     ON_WM_SIZE()
  74.     ON_WM_CREATE()
  75.     //}}AFX_MSG_MAP
  76. END_MESSAGE_MAP()
  77.  
  78.  
  79. void CDrawWnd::DrawLetter(CDC& dc, CPoint pt, int p1[][3],
  80.     int p2[][3], int nLen)
  81. {
  82.  
  83.     for (int i=0;i<nLen;i++)
  84.     {
  85.         int x = (m_nScale*p1[i][0]*(m_nSteps-m_nPos) + m_nScale*p2[i][0]*m_nPos)/m_nSteps;
  86.         int y = (m_nScale*p1[i][1]*(m_nSteps-m_nPos) + m_nScale*p2[i][1]*m_nPos)/m_nSteps;
  87.         if (p1[i][2] == 0)
  88.             dc.MoveTo(pt.x+x, pt.y-y);
  89.         else
  90.             dc.LineTo(pt.x+x, pt.y-y);
  91.     }
  92. }
  93.  
  94. void CDrawWnd::Draw(CDC& dc, int nWidth)
  95. {
  96.     dc.SetPolyFillMode(WINDING);
  97.  
  98.     CPen penblack(PS_SOLID|PS_GEOMETRIC|m_nStyle, nWidth, &m_logbrushBlack);
  99.     CPen penred(PS_SOLID|PS_GEOMETRIC|m_nStyle, nWidth, &m_logbrush);
  100.     CBrush brushBlack(m_logbrushBlack.lbColor);
  101.     CBrush brushRed(m_logbrush.lbColor);
  102.     CRgn rgnNew, rgnBlack;
  103.  
  104.     CPen* pPen = dc.SelectObject(&penred);
  105.  
  106.     dc.BeginPath();
  107.     // letters are 7x9
  108.     // allow 2 units for spacing
  109.  
  110.     CPoint pt(2*m_nScale, m_nHeight/2+(9*m_nScale)/2);
  111.     DrawLetter(dc, pt, letterM, letterC1, 5);
  112.     pt.x += 9*m_nScale;
  113.     DrawLetter(dc, pt, letterF, letterPlus, 6);
  114.     pt.x += 9*m_nScale;
  115.     DrawLetter(dc, pt, letterC2, letterPlus, 6);
  116.  
  117.     dc.EndPath();
  118.     dc.WidenPath();
  119.     rgnNew.CreateFromPath(&dc);
  120.  
  121.     rgnBlack.CreateRectRgn(0,0,0,0);
  122.     rgnBlack.CombineRgn(&m_rgnLast, &rgnNew, RGN_DIFF);
  123.     dc.FillRgn(&rgnBlack, &brushBlack);
  124.     dc.FillRgn(&rgnNew, &brushRed);
  125.  
  126.     dc.SelectObject(pPen);
  127.     m_rgnLast.DeleteObject();
  128.     m_rgnLast.Attach(rgnNew.Detach());
  129. }
  130.  
  131. void CDrawWnd::SetSpeed(int nSpeed)
  132. {
  133.     KillTimer(1);
  134.     VERIFY(SetTimer(1, 50+500-nSpeed*5, NULL) != 0);
  135. }
  136.  
  137. void CDrawWnd::SetResolution(int nRes)
  138. {
  139.     nRes = (nRes < 1) ? 1 : nRes;
  140.     if (nRes != m_nSteps)
  141.     {
  142.         m_nSteps = nRes;
  143.         if (m_nPos > m_nSteps)
  144.             m_nPos = m_nSteps;
  145.         Invalidate();
  146.         UpdateWindow();
  147.     }
  148. }
  149.  
  150. void CDrawWnd::SetPenWidth(int nWidth)
  151. {
  152.     if (nWidth != m_nWidth)
  153.     {
  154.         CRect rect;
  155.         m_nWidth = nWidth;
  156.         Invalidate();
  157.         UpdateWindow();
  158.     }
  159. }
  160.  
  161. void CDrawWnd::SetColor(COLORREF cr)
  162. {
  163.     m_logbrush.lbColor = cr;
  164. }
  165.  
  166. void CDrawWnd::SetLineStyle(int nStyle)
  167. {
  168.     if (nStyle != m_nStyle)
  169.     {
  170.         m_nStyle = nStyle;
  171.         Invalidate();
  172.         UpdateWindow();
  173.     }
  174. }
  175.  
  176. /////////////////////////////////////////////////////////////////////////////
  177. // CDrawWnd message handlers
  178.  
  179. void CDrawWnd::OnTimer(UINT nIDEvent)
  180. {
  181.     if (nIDEvent == 1)
  182.     {
  183.         m_nPos += m_nStep;
  184.         if (m_nPos > m_nSteps || m_nPos < 0)
  185.         {
  186.             m_nStep = -m_nStep;
  187.             m_nPos += m_nStep;
  188.         }
  189.         CClientDC dc(this);
  190.         CRect rect;
  191.         GetClientRect(&rect);
  192.         int nWidth = m_nWidth * rect.Width() + ::GetSystemMetrics(SM_CXSCREEN)/2;
  193.         nWidth = nWidth/::GetSystemMetrics(SM_CXSCREEN);
  194.         Draw(dc, nWidth);
  195.     }
  196.     else
  197.         CWnd::OnTimer(nIDEvent);
  198. }
  199.  
  200. void CDrawWnd::OnPaint()
  201. {
  202.     CPaintDC dc(this); // device context for painting
  203.     m_rgnLast.DeleteObject();
  204.     m_rgnLast.CreateRectRgn(0,0,0,0);
  205.     CBrush brush(RGB(0,0,0));
  206.     CRect rect;
  207.     GetClientRect(rect);
  208.     dc.FillRect(&rect, &brush);
  209.     int nWidth = m_nWidth * rect.Width() + ::GetSystemMetrics(SM_CXSCREEN)/2;
  210.     nWidth = nWidth/::GetSystemMetrics(SM_CXSCREEN);
  211.     Draw(dc, nWidth);
  212.     // Do not call CWnd::OnPaint() for painting messages
  213. }
  214.  
  215. void CDrawWnd::OnSize(UINT nType, int cx, int cy)
  216. {
  217.     CWnd::OnSize(nType, cx, cy);
  218.  
  219.     m_nScale = cx/29;
  220.     m_nHeight = cy;
  221. }
  222.  
  223. int CDrawWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
  224. {
  225.     if (CWnd::OnCreate(lpCreateStruct) == -1)
  226.         return -1;
  227.  
  228.     int nSpeed = AfxGetApp()->GetProfileInt("Config", "Speed", 1);
  229.     if (nSpeed < 0)
  230.         nSpeed = 0;
  231.     SetSpeed(nSpeed);
  232.  
  233.     return 0;
  234. }
  235.  
  236. BOOL CDrawWnd::Create(DWORD dwExStyle, DWORD dwStyle, const RECT& rect,
  237.     CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
  238. {
  239.     // Register a class with no cursor
  240.     if (m_lpszClassName == NULL)
  241.     {
  242.         m_lpszClassName = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,
  243.             ::LoadCursor(AfxGetResourceHandle(),
  244.             MAKEINTRESOURCE(IDC_NULLCURSOR)));
  245.     }
  246.  
  247.     // TODO: Add your specialized code here and/or call the base class
  248.     return CreateEx(dwExStyle, m_lpszClassName, _T(""), dwStyle,
  249.         rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
  250.         pParentWnd->GetSafeHwnd(), NULL, NULL );
  251. }
  252.  
  253. void CDrawWnd::PostNcDestroy()
  254. {
  255.     if (m_bAutoDelete)
  256.         delete this;
  257. }
  258.