MFC起步(1)

类别:编程语言 点击:0 评论:0 推荐:

      我看的是JEFF PROSISE的MFC WINDOWS程序设计,看到第三章时,根据其提供的TICTAG程序,改了一下,做了个简单的五子棋,源码如下,希望能跟学MFC的新手一起进步。
      FIVE.H
//头文件
#define EX 1
#define OH 2
class CMyApp:public CWinApp
{public:
 virtual BOOL InitInstance();
}
;
class CMainWindow:public CWnd
{
protected:
 static const CRect m_rcSquares[25];
 int m_nGameGrid[25];
 int m_nNextChar;
 int GetRectID(CPoint point);
 void DrawBoard(CDC *pDC);
 void DrawX(CDC *pDC,int nPos);
 void DrawO(CDC *pDC,int nPos);
 void ResetGame();
 void CheckForGameOver();
 int IsWinner();
 BOOL IsDraw();
public:
 CMainWindow();
protected:
 virtual void PostNcDestroy();
 afx_msg void OnPaint();
 afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
 afx_msg void OnLButtonDblClk(UINT nFlags,CPoint point);
 afx_msg void OnRButtonDown(UINT nFlags,CPoint point);
 DECLARE_MESSAGE_MAP()
};

FIVE.CPP
// 以下为主程序
#include<afxwin.h>
#include"five.h"
CMyApp myApp;
BOOL CMyApp::InitInstance()
{
 m_pMainWnd=new CMainWindow;
 m_pMainWnd->ShowWindow(m_nCmdShow);
 m_pMainWnd->UpdateWindow();
 return TRUE;
}
BEGIN_MESSAGE_MAP(CMainWindow,CWnd)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()

const CRect CMainWindow::m_rcSquares[25]=
{
 CRect(16,16,32,32),
    CRect(32,16,48,32),
    CRect(48,16,64,32),
 CRect(64,16,80,32),
 CRect(80,16,96,32),
 
 CRect(16,32,32,48),
 CRect(32,32,48,48),
 CRect(48,32,64,48),
 CRect(64,32,80,48),
 CRect(80,32,96,48),

 CRect(16,48,32,64),
 CRect(32,48,48,64),
 CRect(48,48,64,64),
 CRect(64,48,80,64),
 CRect(80,48,96,64),

 CRect(16,64,32,80),
 CRect(32,64,48,80),
 CRect(48,64,64,80),
 CRect(64,64,80,80),
 CRect(80,64,96,80),

 CRect(16,80,32,96),
 CRect(32,80,48,96),
 CRect(48,80,64,96),
 CRect(64,80,80,96),
 CRect(80,80,96,96)
};

CMainWindow::CMainWindow()
{
 m_nNextChar=EX;
 ::ZeroMemory(m_nGameGrid,25*sizeof(int));
 CString strWndClass=AfxRegisterWndClass(
  CS_DBLCLKS,
  AfxGetApp()->LoadStandardCursor(IDC_ARROW),
  (HBRUSH)(COLOR_3DFACE+1),
  AfxGetApp()->LoadStandardIcon(IDI_WINLOGO)
  );

  CreateEx(0,strWndClass,_T("五子棋"),
  WS_OVERLAPPED|WS_SYSMENU|WS_CAPTION|WS_MINIMIZEBOX,
  CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
  NULL,NULL);
 CRect rect(0,0,96,96);
 CalcWindowRect(&rect);
 SetWindowPos(NULL,0,0,rect.Width(),rect.Height(),
  SWP_NOZORDER|SWP_NOMOVE|SWP_NOREDRAW);
};

void CMainWindow::PostNcDestroy()
{delete this;
}
void CMainWindow::OnPaint()
{CPaintDC dc(this);
DrawBoard(&dc);
}

void CMainWindow::OnLButtonDown(UINT nFlags,CPoint point)
{if(m_nNextChar!=EX)
return;
int nPos=GetRectID(point);
if((nPos==-1)||(m_nGameGrid[nPos]!=0))
return;
m_nGameGrid[nPos]=EX;
m_nNextChar=OH;
CClientDC dc(this);
DrawX(&dc,nPos);
CheckForGameOver();
}
void CMainWindow::OnRButtonDown(UINT nFlags,CPoint point)
{
 if(m_nNextChar!=OH)
 return;
 int nPos=GetRectID(point);
 if((nPos==-1)||(m_nGameGrid[nPos]!=0))
  return;
 m_nGameGrid[nPos]=OH;
 m_nNextChar=EX;
 CClientDC dc(this);
 DrawO(&dc,nPos);
 CheckForGameOver();

}

void CMainWindow::OnLButtonDblClk(UINT nFlags,CPoint point)
{
 CClientDC dc(this);
 if (dc.GetPixel(point)==RGB(0,0,0))
  ResetGame();
}
int CMainWindow::GetRectID(CPoint point)
{
 for(int i=0;i<25;i++)
 {  
  if(m_rcSquares[i].PtInRect(point))
   return i;
 }
 return -1;
}

void CMainWindow::DrawBoard(CDC *pDC)
{
 CPen pen(PS_SOLID,5,RGB(0,0,0));
 CPen *pOldPen=pDC->SelectObject(&pen);
 pDC->MoveTo(16,32);
 pDC->LineTo(96,32);
 pDC->MoveTo(16,48);
 pDC->LineTo(96,48);
 pDC->MoveTo(16,64);
 pDC->LineTo(96,64);
 pDC->MoveTo(16,80);
 pDC->LineTo(96,80);
 
 pDC->MoveTo(32,16);
 pDC->LineTo(32,96);
 pDC->MoveTo(48,16);
 pDC->LineTo(48,96);
 pDC->MoveTo(64,16);
 pDC->LineTo(64,96);
 pDC->MoveTo(80,16);
 pDC->LineTo(80,96);
 
 for(int i=0;i<25;i++)
 {
  if(m_nGameGrid[i]==EX)
   DrawX(pDC,i);
  else if(m_nGameGrid[i]==OH)
   DrawO(pDC,i);
 }
  pDC->SelectObject(pOldPen);
 }

 void CMainWindow::DrawX(CDC *pDC,int nPos)
 {
  CPen pen(PS_SOLID,4,RGB(255,0,0));
  CPen *pOldPen=pDC->SelectObject(&pen);
  CRect rect=m_rcSquares[nPos];
  rect.DeflateRect(16,16);
  pDC->MoveTo(rect.left,rect.top);
  pDC->LineTo(rect.right,rect.bottom);
  pDC->MoveTo(rect.left,rect.bottom);
  pDC->LineTo(rect.right,rect.top);
  pDC->SelectObject(pOldPen);
 }

 void CMainWindow::DrawO(CDC *pDC, int nPos)
 {
  CPen pen(PS_SOLID,2,RGB(12,33,255));
  CPen *pOldPen=pDC->SelectObject(&pen);
  CRect rect=m_rcSquares[nPos];
  rect.DeflateRect(16,16);
  pDC->MoveTo(rect.left,rect.top);
  pDC->LineTo(rect.right,rect.bottom);
  pDC->MoveTo(rect.left,rect.bottom);
  pDC->LineTo(rect.right,rect.top);
  pDC->SelectObject(pOldPen);
 }
 void CMainWindow::CheckForGameOver()
 {
  int nWinner;
  if(nWinner=IsWinner())
  {
   CString string=(nWinner==EX)?_T("X Wins!"):_T("O Wins!");
   MessageBox(string,_T("Game Over"),MB_ICONEXCLAMATION|MB_OK);
   ResetGame();
  }
  else if(IsDraw())
  {
   MessageBox(_T("It's a draw!"),_T("Game Over"),MB_ICONEXCLAMATION|MB_OK);
   ResetGame();
  }
 }

 int CMainWindow::IsWinner()
 {
  static int nPattern[12][5]={
   0,1,2,3,4,
   5,6,7,8,9,
   10,11,12,13,14,
   15,16,17,18,19,
   20,21,22,23,24,
           
   0,5,10,15,20,
   1,6,11,16,21,
   2,7,12,17,22,
   3,8,13,18,23,
   4,9,14,19,24,

   4,8,12,16,20,
   0,6,12,18,24
  };
  for(int i=0;i<12;i++)
  {
   if((m_nGameGrid[nPattern[i][0]]==EX)&&
      (m_nGameGrid[nPattern[i][1]]==EX)&&
      (m_nGameGrid[nPattern[i][2]]==EX)&&
      (m_nGameGrid[nPattern[i][3]]==EX)&&
      (m_nGameGrid[nPattern[i][4]]==EX))
      return EX;
   if((m_nGameGrid[nPattern[i][0]]==OH)&&
      (m_nGameGrid[nPattern[i][1]]==OH)&&
      (m_nGameGrid[nPattern[i][2]]==OH)&&
      (m_nGameGrid[nPattern[i][3]]==OH)&&
      (m_nGameGrid[nPattern[i][4]]==OH))
      return OH;
  }
  return 0;
 }

 BOOL CMainWindow::IsDraw()
 {
  for(int i=0;i<9;i++)
  {
   if(m_nGameGrid[i]==0)
    return FALSE;
  }
  return TRUE;
 }

 void CMainWindow::ResetGame()
 {
  m_nNextChar=EX;
  ::ZeroMemory(m_nGameGrid,25*sizeof(int));
  Invalidate();
 }


下一节,我将详细解释代码的运行原理!

 



 

本文地址:http://com.8s8s.com/it/it24613.htm