我看的是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(); }
下一节,我将详细解释代码的运行原理!

|