先给出最终效果
代码(没法一点一点讲了,太长)
checkvw.h
checkvw.cpp
// checkvw.h : interface of the CCheckerView class
//
/
class CCheckerView : public CView
{
protected: // create from serialization only
CCheckerView();
DECLARE_DYNCREATE(CCheckerView)
// Attributes
public:
CCheckerDoc* GetDocument();
COLORREF m_background;
// Operations
public:
void DrawCell(CDC *dc,CCheckerDoc *doc,int x,int y);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCheckerView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CCheckerView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
BOOL Screen2Grid(CPoint &pt);
BOOL Grid2Screen(CPoint &pt);
// Generated message map functions
protected:
//{{AFX_MSG(CCheckerView)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnStatus();
afx_msg void OnBackground();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in checkvw.cpp
inline CCheckerDoc* CCheckerView::GetDocument()
{ return (CCheckerDoc*)m_pDocument; }
#endif
/
// checkvw.cpp : implementation of the CCheckerView class
//
#include "stdafx.h"
#include "checker.h"
#include "checkdoc.h"
#include "checkvw.h"
#include "actdlg.h"
#include "statuspg.h"
#include "customco.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/
// CCheckerView
IMPLEMENT_DYNCREATE(CCheckerView, CView)
BEGIN_MESSAGE_MAP(CCheckerView, CView)
//{{AFX_MSG_MAP(CCheckerView)
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_COMMAND(IDM_STATUS, OnStatus)
ON_COMMAND(IDM_BACKGROUND, OnBackground)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/
// CCheckerView construction/destruction
CCheckerView::CCheckerView()
{
m_background=RGB(0x80,0x80,0x80);
}
CCheckerView::~CCheckerView()
{
}
/
// CCheckerView drawing
void CCheckerView::DrawCell(CDC *dc,CCheckerDoc *doc,int x,int y)
{
CBrush white(RGB(0xFF,0xFF,0xFF)),black(RGB(0,0,0)),red(RGB(0xFF,0,0));
CBrush grey(m_background),cyan(RGB(0,0xff,0xff));
CBrush *old,*circ=NULL;
CPoint sel;
STATE state=doc->CellState(x,y);
old=dc->SelectObject(x%2==y%2?&white:&grey);
if (doc->GetSelect(sel)&&sel.x==x&&sel.y==y)
dc->SelectObject(&cyan); // draw selection if appropriate
dc->Rectangle(x*75,y*50,(x+1)*75,(y+1)*50);
switch(state)
{
case CELL_RED:
case CELL_REDKING:
circ=&red;
break;
case CELL_BLACK:
case CELL_BLACKKING:
circ=&black;
break;
}
if (circ)
{
dc->SelectObject(circ);
dc->Ellipse(x*75+5,y*50+5,(x+1)*75-5,(y+1)*50-5);
}
if (state==CELL_REDKING||state==CELL_BLACKKING)
{
CPen *oldpen=(CPen *)dc->SelectStockObject(WHITE_PEN);
dc->Ellipse(x*75+10,y*50+10,(x+1)*75-10,(y+1)*50-10);
dc->SelectObject(oldpen);
}
dc->SelectObject(old);
}
void CCheckerView::OnDraw(CDC* pDC)
{
CCheckerDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
int i,j;
for (i=0;i<8;i++)
for (j=0;j<8;j++)
DrawCell(pDC,pDoc,j,i);
}
/
// CCheckerView printing
BOOL CCheckerView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CCheckerView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CCheckerView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/
// CCheckerView diagnostics
#ifdef _DEBUG
void CCheckerView::AssertValid() const
{
CView::AssertValid();
}
void CCheckerView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CCheckerDoc* CCheckerView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCheckerDoc)));
return (CCheckerDoc*)m_pDocument;
}
#endif //_DEBUG
BOOL CCheckerView::Screen2Grid(CPoint &pt)
{
pt.x/=75;
pt.y/=50;
return TRUE;
}
BOOL CCheckerView::Grid2Screen(CPoint &pt)
{
pt.x*=75;
pt.y*=50;
return TRUE;
}
/
// CCheckerView message handlers
void CCheckerView::OnLButtonDown(UINT nFlags, CPoint point)
{
CCheckerDoc *doc=GetDocument();
CPoint select;
Screen2Grid(point);
if (doc->GetSelect(select))
{
if (select!=point)
{
doc->movenum++;
doc->SetCellState(point.x,point.y,doc->CellState(select.x,select.y));
doc->SetCellState(select.x,select.y,CELL_EMPTY);
}
doc->ClrSelect();
}
else
if (doc->CellState(point.x,point.y)!=CELL_EMPTY)
doc->SetSelect(point);
CView::OnLButtonDown(nFlags, point);
}
void CCheckerView::OnRButtonDown(UINT nFlags, CPoint point)
{
CCheckerDoc *doc=GetDocument();
Screen2Grid(point);
STATE state=doc->CellState(point.x,point.y);
if (state==CELL_EMPTY) return;
ActionDialog action;
action.m_movenum=doc->movenum;
action.m_action=0;
if (action.DoModal()==IDOK)
{
doc->movenum=action.m_movenum;
switch (action.m_action)
{
case 0:
doc->SetCellState(point.x,point.y,CELL_EMPTY);
doc->ClrSelect();
break;
case 1:
if (state==CELL_RED||state==CELL_BLACK)
doc->SetCellState(point.x,point.y,(STATE)(state+2));
break;
}
doc->ClrSelect();
doc->UpdateAllViews(NULL,(LPARAM)&point);
}
CView::OnRButtonDown(nFlags, point);
}
void CCheckerView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
if (!lHint)
{
CView::OnUpdate(pSender,lHint,pHint);
return;
}
CPoint pt=*(CPoint *)lHint;
CSize sz(75,50);
Grid2Screen(pt);
CRect r(pt,sz);
InvalidateRect(&r);
}
void CCheckerView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
if (pDC->IsPrinting())
{
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->ScaleViewportExt(2,1,2,1); // double size
}
CView::OnPrepareDC(pDC, pInfo);
}
void CCheckerView::OnStatus()
{
CCheckerDoc *doc=GetDocument();
CPropertySheet sheet("Game Status",this);
StatusPage redpg(IDS_RED), blackpg(IDS_BLACK);
// Init page data
redpg.m_pieces.Format("%d",doc->Count(CELL_RED));
redpg.m_kings.Format("%d",doc->Count(CELL_REDKING));
blackpg.m_pieces.Format("%d",doc->Count(CELL_BLACK));
blackpg.m_kings.Format("%d",doc->Count(CELL_BLACKKING));
sheet.AddPage(&redpg);
sheet.AddPage(&blackpg);
sheet.DoModal();
}
void CCheckerView::OnBackground()
{
CCustomColor dlg(m_background,0,this);
if (dlg.DoModal()==IDOK)
{
if (dlg.m_reset)
m_background=RGB(0x80,0x80,0x80);
else
m_background=dlg.GetColor();
InvalidateRect(NULL);
}
}
/
// CAboutDlg dialog used for App About
class CCircButton : public CButton
{
public:
void DrawItem(LPDRAWITEMSTRUCT di);
};
void CCircButton::DrawItem(LPDRAWITEMSTRUCT di)
{
CString title;
int oldbk;
// Could set background/foregroud colors but Windows
// sets reasonable defaults for you
CDC *dc=CDC::FromHandle(di->hDC);
dc->Ellipse(&di->rcItem);
GetWindowText(title);
oldbk=dc->SetBkMode(TRANSPARENT);
dc->DrawText(title,-1,&di->rcItem,DT_CENTER|DT_SINGLELINE|DT_VCENTER);
dc->SetBkMode(oldbk);
}
class CCustomColor : public CColorDialog
{
// Construction
public:
CCustomColor(COLORREF color=0,DWORD flag=0,CWnd* pParent = NULL); // standard constructor
BOOL m_reset;
// Dialog Data
//{{AFX_DATA(CCustomColor)
enum { IDD = IDD_COLOR };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCustomColor)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CCustomColor)
afx_msg void OnReset();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// Nested splitter class -- Williams
class CNestSplit : public CSplitterWnd
{
protected:
BOOL SplitRow(int cybefore);
BOOL SplitColumn(int cxbefore);
private:
void SetMeActive(void);
};
/* Stateary.h */
#include <afxtempl.h>
enum STATE { CELL_EMPTY=0, CELL_RED, CELL_BLACK, CELL_REDKING, CELL_BLACKKING };
typedef CArray<STATE,STATE> CStateArray;
class CStateArray2 : public CStateArray
{
protected:
int maxx,maxy;
public:
CStateArray2(int mx,int my) { maxx=mx; maxy=my; SetSize(mx*my); };
STATE GetAt(int x,int y) { return CStateArray::GetAt(x*maxx+y); };
void SetAt(int x,int y,STATE v) { CStateArray::SetAt(x*maxx+y,v); };
void Serialize(CArchive &ar);
};
// textdoc.h : header file
//
/
// CTextDoc document
class CTextDoc : public CDocument
{
protected:
CTextDoc(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CTextDoc)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTextDoc)
protected:
virtual BOOL OnNewDocument();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CTextDoc();
virtual void Serialize(CArchive& ar); // overridden for document i/o
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
protected:
//{{AFX_MSG(CTextDoc)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// debugvw.h : header file
//
/
// DebugView view
class DebugView : public CScrollView
{
public:
DebugView(); // class wizard makes this protected but I want pubic!
protected:
DECLARE_DYNCREATE(DebugView)
// Attributes
public:
protected:
int m_linehi;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(DebugView)
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual void OnInitialUpdate(); // first time after construct
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~DebugView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
//{{AFX_MSG(DebugView)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/
// statuspg.h : header file
//
/
// StatusPage dialog
class StatusPage : public CPropertyPage
{
DECLARE_DYNCREATE(StatusPage)
// only for serialization
StatusPage() : CPropertyPage(StatusPage::IDD) {};
// Construction
public:
StatusPage(UINT title);
~StatusPage();
// Dialog Data
//{{AFX_DATA(StatusPage)
enum { IDD = IDD_STATUS };
CString m_kings;
CString m_pieces;
//}}AFX_DATA
// Overrides
// ClassWizard generate virtual function overrides
//{{AFX_VIRTUAL(StatusPage)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(StatusPage)
// NOTE: the ClassWizard will add member functions here
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// actdlgh : header file
//
/
// ActionDialog dialog
class ActionDialog : public CDialog
{
// Construction
public:
ActionDialog(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(ActionDialog)
enum { IDD = IDD_ACTIONDLG };
UINT m_movenum;
int m_action;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(ActionDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(ActionDialog)
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// Implementation
protected:
CCircButton okbutton;
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//{{AFX_MSG(CAboutDlg)
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// App command to run the dialog
void CCheckerApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
/
// CCheckerApp commands
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
okbutton.SubclassDlgItem(IDOK,this);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
// checker.h : main header file for the CHECKER1 application
//
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/
// CCheckerApp:
// See checker.cpp for the implementation of this class
//
class CCheckerApp : public CWinApp
{
public:
CCheckerApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCheckerApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CCheckerApp)
afx_msg void OnAppAbout();
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/
// checkdoc.h : interface of the CCheckerDoc class
//
/
#include "stateary.h"
class CCheckerDoc : public CDocument
{
protected: // create from serialization only
CCheckerDoc();
DECLARE_DYNCREATE(CCheckerDoc)
CStateArray2 m_statearray;
CPoint m_selected;
BOOL m_selectflag;
unsigned movenum; // move number
// Attributes
public:
BOOL GetSelect(CPoint &pt) { pt=m_selected; return m_selectflag; };
void SetSelect(CPoint pt) { m_selected=pt; m_selectflag=TRUE; UpdateAllViews(NULL,(LPARAM)&pt); };
void ClrSelect(void) { if (m_selectflag) m_selectflag=FALSE; UpdateAllViews(NULL,(LPARAM)&m_selected); };
int Count(STATE typ);
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCheckerDoc)
public:
virtual BOOL OnNewDocument();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CCheckerDoc();
virtual void Serialize(CArchive& ar); // overridden for document i/o
STATE CellState(int,int);
void SetCellState(int x,int y,STATE s);
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CCheckerDoc)
afx_msg void OnDebugwin();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/
// checkdoc.cpp : implementation of the CCheckerDoc class
//
#include "stdafx.h"
#include "checker.h"
#include "checkdoc.h"
#include "debugvw.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/
// CCheckerDoc
IMPLEMENT_DYNCREATE(CCheckerDoc, CDocument)
BEGIN_MESSAGE_MAP(CCheckerDoc, CDocument)
//{{AFX_MSG_MAP(CCheckerDoc)
ON_COMMAND(IDM_DEBUGWIN, OnDebugwin)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CCheckerDoc construction/destruction
CCheckerDoc::CCheckerDoc() : m_statearray(8,8)
{
int x,y;
m_selectflag=FALSE;
for (y=0;y<3;y++)
for (x=!(y%2);x<8;x+=2)
m_statearray.SetAt(x,y,CELL_BLACK);
for (y=5;y<8;y++)
for (x=!(y%2);x<8;x+=2)
m_statearray.SetAt(x,y,CELL_RED);
movenum=0;
}
CCheckerDoc::~CCheckerDoc()
{
}
BOOL CCheckerDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/
// CCheckerDoc serialization
void CCheckerDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
ar<<(DWORD)movenum;
else
{
DWORD move;
ar>>move;
movenum=move;
}
m_statearray.Serialize(ar);
}
/
// CCheckerDoc diagnostics
#ifdef _DEBUG
void CCheckerDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CCheckerDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/
// CCheckerDoc commands
STATE CCheckerDoc::CellState(int x,int y)
{
return m_statearray.GetAt(x,y);
}
void CCheckerDoc::SetCellState(int x,int y,STATE s)
{
CPoint pt(x,y);
m_statearray.SetAt(x,y,s);
UpdateAllViews(NULL,(LPARAM)&pt);
SetModifiedFlag();
}
// Count cells -- if typ==CELL_RED count CELL_RED and CELL_REDKING
// if typ==CELL_BLACK count CELL_BLACK and CELL_BLACKKING
int CCheckerDoc::Count(STATE typ)
{
int i,max=m_statearray.GetUpperBound(),ct=0;
if (max==-1) return 0;
for (i=0;i<=max;i++)
{
STATE s=m_statearray[i];
if (typ==s) ct++;
if (typ==CELL_RED && s==CELL_REDKING) ct++;
if (typ==CELL_BLACK && s==CELL_BLACKKING) ct++;
}
return ct;
}
void CCheckerDoc::OnDebugwin()
{
#if 1 // Easy way to make a new view -- use doc templates
CMultiDocTemplate temptemplate(IDR_DEBUGTYPE,RUNTIME_CLASS(CCheckerDoc),
RUNTIME_CLASS(CMDIChildWnd),RUNTIME_CLASS(DebugView));
CFrameWnd *frame=temptemplate.CreateNewFrame(this,NULL);
if (!frame)
AfxMessageBox("Can't create debug window");
else
frame->InitialUpdateFrame(this,TRUE);
#else // hard way -- do all the work yourself
CMDIChildWnd *frame=new CMDIChildWnd;
if (!frame->Create(NULL,"Debug output: "+GetTitle()))
{
AfxMessageBox("Can't create debug window frame");
return;
}
DebugView *view=new DebugView;
// Don't care about size -- RecalcLayout will resize anyway.
if (!view->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW,CRect(0,0,0,0),frame,AFX_IDW_PANE_FIRST))
{
AfxMessageBox("Can't create debug window view");
frame->DestroyWindow();
}
// add view to document (this)
AddView(view);
// Make sure OnInitialUpdate fires
frame->InitialUpdateFrame(this,TRUE);
// Layout frame
frame->RecalcLayout();
#endif
}
// checkvw.cpp : implementation of the CCheckerView class
//
#include "stdafx.h"
#include "checker.h"
#include "checkdoc.h"
#include "checkvw.h"
#include "actdlg.h"
#include "statuspg.h"
#include "customco.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/
// CCheckerView
IMPLEMENT_DYNCREATE(CCheckerView, CView)
BEGIN_MESSAGE_MAP(CCheckerView, CView)
//{{AFX_MSG_MAP(CCheckerView)
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_COMMAND(IDM_STATUS, OnStatus)
ON_COMMAND(IDM_BACKGROUND, OnBackground)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/
// CCheckerView construction/destruction
CCheckerView::CCheckerView()
{
m_background=RGB(0x80,0x80,0x80);
}
CCheckerView::~CCheckerView()
{
}
/
// CCheckerView drawing
void CCheckerView::DrawCell(CDC *dc,CCheckerDoc *doc,int x,int y)
{
CBrush white(RGB(0xFF,0xFF,0xFF)),black(RGB(0,0,0)),red(RGB(0xFF,0,0));
CBrush grey(m_background),cyan(RGB(0,0xff,0xff));
CBrush *old,*circ=NULL;
CPoint sel;
STATE state=doc->CellState(x,y);
old=dc->SelectObject(x%2==y%2?&white:&grey);
if (doc->GetSelect(sel)&&sel.x==x&&sel.y==y)
dc->SelectObject(&cyan); // draw selection if appropriate
dc->Rectangle(x*75,y*50,(x+1)*75,(y+1)*50);
switch(state)
{
case CELL_RED:
case CELL_REDKING:
circ=&red;
break;
case CELL_BLACK:
case CELL_BLACKKING:
circ=&black;
break;
}
if (circ)
{
dc->SelectObject(circ);
dc->Ellipse(x*75+5,y*50+5,(x+1)*75-5,(y+1)*50-5);
}
if (state==CELL_REDKING||state==CELL_BLACKKING)
{
CPen *oldpen=(CPen *)dc->SelectStockObject(WHITE_PEN);
dc->Ellipse(x*75+10,y*50+10,(x+1)*75-10,(y+1)*50-10);
dc->SelectObject(oldpen);
}
dc->SelectObject(old);
}
void CCheckerView::OnDraw(CDC* pDC)
{
CCheckerDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
int i,j;
for (i=0;i<8;i++)
for (j=0;j<8;j++)
DrawCell(pDC,pDoc,j,i);
}
/
// CCheckerView printing
BOOL CCheckerView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CCheckerView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CCheckerView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/
// CCheckerView diagnostics
#ifdef _DEBUG
void CCheckerView::AssertValid() const
{
CView::AssertValid();
}
void CCheckerView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CCheckerDoc* CCheckerView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCheckerDoc)));
return (CCheckerDoc*)m_pDocument;
}
#endif //_DEBUG
BOOL CCheckerView::Screen2Grid(CPoint &pt)
{
pt.x/=75;
pt.y/=50;
return TRUE;
}
BOOL CCheckerView::Grid2Screen(CPoint &pt)
{
pt.x*=75;
pt.y*=50;
return TRUE;
}
/
// CCheckerView message handlers
void CCheckerView::OnLButtonDown(UINT nFlags, CPoint point)
{
CCheckerDoc *doc=GetDocument();
CPoint select;
Screen2Grid(point);
if (doc->GetSelect(select))
{
if (select!=point)
{
doc->movenum++;
doc->SetCellState(point.x,point.y,doc->CellState(select.x,select.y));
doc->SetCellState(select.x,select.y,CELL_EMPTY);
}
doc->ClrSelect();
}
else
if (doc->CellState(point.x,point.y)!=CELL_EMPTY)
doc->SetSelect(point);
CView::OnLButtonDown(nFlags, point);
}
void CCheckerView::OnRButtonDown(UINT nFlags, CPoint point)
{
CCheckerDoc *doc=GetDocument();
Screen2Grid(point);
STATE state=doc->CellState(point.x,point.y);
if (state==CELL_EMPTY) return;
ActionDialog action;
action.m_movenum=doc->movenum;
action.m_action=0;
if (action.DoModal()==IDOK)
{
doc->movenum=action.m_movenum;
switch (action.m_action)
{
case 0:
doc->SetCellState(point.x,point.y,CELL_EMPTY);
doc->ClrSelect();
break;
case 1:
if (state==CELL_RED||state==CELL_BLACK)
doc->SetCellState(point.x,point.y,(STATE)(state+2));
break;
}
doc->ClrSelect();
doc->UpdateAllViews(NULL,(LPARAM)&point);
}
CView::OnRButtonDown(nFlags, point);
}
void CCheckerView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
if (!lHint)
{
CView::OnUpdate(pSender,lHint,pHint);
return;
}
CPoint pt=*(CPoint *)lHint;
CSize sz(75,50);
Grid2Screen(pt);
CRect r(pt,sz);
InvalidateRect(&r);
}
void CCheckerView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
if (pDC->IsPrinting())
{
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->ScaleViewportExt(2,1,2,1); // double size
}
CView::OnPrepareDC(pDC, pInfo);
}
void CCheckerView::OnStatus()
{
CCheckerDoc *doc=GetDocument();
CPropertySheet sheet("Game Status",this);
StatusPage redpg(IDS_RED), blackpg(IDS_BLACK);
// Init page data
redpg.m_pieces.Format("%d",doc->Count(CELL_RED));
redpg.m_kings.Format("%d",doc->Count(CELL_REDKING));
blackpg.m_pieces.Format("%d",doc->Count(CELL_BLACK));
blackpg.m_kings.Format("%d",doc->Count(CELL_BLACKKING));
sheet.AddPage(&redpg);
sheet.AddPage(&blackpg);
sheet.DoModal();
}
void CCheckerView::OnBackground()
{
CCustomColor dlg(m_background,0,this);
if (dlg.DoModal()==IDOK)
{
if (dlg.m_reset)
m_background=RGB(0x80,0x80,0x80);
else
m_background=dlg.GetColor();
InvalidateRect(NULL);
}
}
// checkfrm.cpp : implementation file
//
#include "stdafx.h"
#include "checker.h"
#include "checkfrm.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/
// CCheckFrame
IMPLEMENT_DYNCREATE(CCheckFrame, CMDIChildWnd)
CCheckFrame::CCheckFrame()
{
}
CCheckFrame::~CCheckFrame()
{
}
BEGIN_MESSAGE_MAP(CCheckFrame, CMDIChildWnd)
//{{AFX_MSG_MAP(CCheckFrame)
ON_WM_GETMINMAXINFO()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CCheckFrame message handlers
void CCheckFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
CRect sz(0,0,601,401);
DWORD styles,exstyles;
styles=::GetWindowLong(m_hWnd,GWL_STYLE);
exstyles=::GetWindowLong(m_hWnd,GWL_EXSTYLE);
// Leave room for view's border
sz.InflateRect(::GetSystemMetrics(SM_CXBORDER),::GetSystemMetrics(SM_CYBORDER));
::AdjustWindowRectEx(&sz,styles,FALSE,exstyles);
CPoint size(sz.Width(),sz.Height());
lpMMI->ptMaxTrackSize=lpMMI->ptMinTrackSize=lpMMI->ptMaxSize=size;
lpMMI->ptMaxPosition=CPoint(0,0);
}