www.pudn.com > Hanoi_Src.rar > HanoiDlg.cpp
// HanoiDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Hanoi.h"
#include "HanoiDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
afx_msg void OnBest();
//}}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)
ON_BN_CLICKED(IDC_BEST, OnBest)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHanoiDlg dialog
CHanoiDlg::CHanoiDlg(CWnd* pParent /*=NULL*/)
: CDialog(CHanoiDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CHanoiDlg)
m_nDiskNum = 1;
m_nQueryNum = 1;
m_strMoveShow = _T("");
m_strQueryShow = _T("");
m_nMoveNum = 0;
m_bAuto = FALSE;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CHanoiDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHanoiDlg)
DDX_Text(pDX, IDC_DISKNUM, m_nDiskNum);
DDX_Text(pDX, IDC_QUERYNUM, m_nQueryNum);
DDX_Text(pDX, IDC_MOVESHOW, m_strMoveShow);
DDX_Text(pDX, IDC_QUERYSHOW, m_strQueryShow);
DDX_Text(pDX, IDC_MOVENUM, m_nMoveNum);
DDX_Check(pDX, IDC_AUTO, m_bAuto);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CHanoiDlg, CDialog)
//{{AFX_MSG_MAP(CHanoiDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_QUERY, OnQuery)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHanoiDlg message handlers
BOOL CHanoiDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CHanoiDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CHanoiDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
// 在静态控件内绘图
CWnd * pWnd=GetDlgItem(IDC_PICSHOW);
CDC * pControlDC=pWnd->GetDC();
pWnd->Invalidate();
pWnd->UpdateWindow();
// 画柱子
pControlDC->SelectStockObject(LTGRAY_BRUSH);
pControlDC->Rectangle(LEFT+53,UP,LEFT+57,DOWN+1);
pControlDC->Rectangle(LEFT,DOWN,LEFT+110,DOWN+3);
pControlDC->SelectStockObject(HOLLOW_BRUSH);
pControlDC->Rectangle(LEFT+168,UP,LEFT+172,DOWN+1);
pControlDC->Rectangle(LEFT+115,DOWN,LEFT+225,DOWN+3);
pControlDC->SelectStockObject(WHITE_BRUSH);
pControlDC->Rectangle(LEFT+283,UP,LEFT+287,DOWN+1);
pControlDC->Rectangle(LEFT+230,DOWN,RIGHT,DOWN+3);
pControlDC->SetBkMode(TRANSPARENT);
pControlDC->TextOut(LEFT+51,DOWN+1,"A");
pControlDC->TextOut(LEFT+166,DOWN+1,"B");
pControlDC->TextOut(LEFT+281,DOWN+1,"C");
pWnd->ReleaseDC(pControlDC);
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CHanoiDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CHanoiDlg::OnOK()
{
UpdateData(TRUE);
if(m_nDiskNum<1)
{
AfxMessageBox("盘子个数应大于0!");
return;
}
if(m_nDiskNum<=10)
{
m_nDiskHeight=15;
}
else
{
m_nDiskHeight=HEIGHT/m_nDiskNum;
}
MoveTxt.RemoveAll();
m_strMoveShow="";
m_strQueryShow="";
m_nMoveNum=0;
UpdateData(FALSE);
DiskA.RemoveAll();
DiskA.SetSize(m_nDiskNum+1);
DiskA[0]='A';
for(UINT i=1;i<=m_nDiskNum;i++)
{
DiskA[i]=m_nDiskNum-i+1;
}
DiskB.RemoveAll();
DiskB.Add('B');
DiskC.RemoveAll();
DiskC.Add('C');
RedrawWindow();
DrawDiskA();
Hanoi(m_nDiskNum,DiskA,DiskB,DiskC);
UpdateData(FALSE);
}
void CHanoiDlg::OnQuery()
{
UpdateData(TRUE);
if(m_nQueryNum<1||m_nQueryNum>m_nMoveNum)
{
AfxMessageBox("该步骤不存在,请重新输入!");
return;
}
m_strQueryShow=MoveTxt[m_nQueryNum-1];
UpdateData(FALSE);
}
void CHanoiDlg::Hanoi(UINT n,CUIntArray& diska,
CUIntArray& diskb,CUIntArray& diskc)
{
if(n==1)
{
Move(diska,diskc);
}
else
{
Hanoi(n-1,diska,diskc,diskb);
Move(diska,diskc);
Hanoi(n-1,diskb,diska,diskc);
}
}
void CHanoiDlg::Move(CUIntArray& from,CUIntArray& to)
{
if(!m_bAuto)
{
CNextDlg nextdlg;
nextdlg.DoModal();
}
m_nMoveNum++;
CString tmpstr;
tmpstr.Format("%d. %c ---> %c \r\n",m_nMoveNum,from[0],to[0]);
MoveTxt.Add(tmpstr);
m_strMoveShow+=tmpstr;
UpdateData(FALSE);
UINT tmpnum;
tmpnum=from.GetAt(from.GetUpperBound());
from.RemoveAt(from.GetUpperBound());
to.Add(tmpnum);
RedrawWindow();
if('A'!=from[0]&&'A'!=to[0])
{
DrawDiskA();
}
if('B'!=from[0]&&'B'!=to[0])
{
DrawDiskB();
}
if('C'!=from[0]&&'C'!=to[0])
{
DrawDiskC();
}
DrawDisk(from[0]);
DrawDisk(to[0]);
}
void CHanoiDlg::DrawDisk(UINT Which)
{
switch(Which)
{
case 'A':
DrawDiskA();
break;
case 'B':
DrawDiskB();
break;
case 'C':
DrawDiskC();
break;
}
}
void CHanoiDlg::DrawDiskA()
{
CWnd * pWnd=GetDlgItem(IDC_PICSHOW);
CDC * pControlDC=pWnd->GetDC();
pControlDC->SelectStockObject(LTGRAY_BRUSH);
UINT disknum=DiskA.GetSize()-1;
UINT cx=LEFT+55;
for(UINT i=1;i<=disknum;i++)
{
UINT width=WIDTH*DiskA[i]/(m_nDiskNum*2);
pControlDC->Rectangle(cx-width,DOWN-(i-1)*m_nDiskHeight,
cx+width,DOWN-i*m_nDiskHeight);
char str[3];
itoa(DiskA[i],str,10);
pControlDC->SetBkMode(TRANSPARENT);
pControlDC->TextOut(cx-4,DOWN-i*m_nDiskHeight-1,str);
}
pWnd->ReleaseDC(pControlDC);
}
void CHanoiDlg::DrawDiskB()
{
CWnd * pWnd=GetDlgItem(IDC_PICSHOW);
CDC * pControlDC=pWnd->GetDC();
pControlDC->SelectStockObject(HOLLOW_BRUSH);
UINT disknum=DiskB.GetSize()-1;
UINT cx=LEFT+170;
for(UINT i=1;i<=disknum;i++)
{
UINT width=WIDTH*DiskB[i]/(m_nDiskNum*2);
pControlDC->Rectangle(cx-width,DOWN-(i-1)*m_nDiskHeight,
cx+width,DOWN-i*m_nDiskHeight);
char str[3];
itoa(DiskB[i],str,10);
pControlDC->SetBkMode(TRANSPARENT);
pControlDC->TextOut(cx-4,DOWN-i*m_nDiskHeight-1,str);
}
pWnd->ReleaseDC(pControlDC);
}
void CHanoiDlg::DrawDiskC()
{
CWnd * pWnd=GetDlgItem(IDC_PICSHOW);
CDC * pControlDC=pWnd->GetDC();
pControlDC->SelectStockObject(WHITE_BRUSH);
UINT disknum=DiskC.GetSize()-1;
UINT cx=LEFT+285;
for(UINT i=1;i<=disknum;i++)
{
UINT width=WIDTH*DiskC[i]/(m_nDiskNum*2);
pControlDC->Rectangle(cx-width,DOWN-(i-1)*m_nDiskHeight,
cx+width,DOWN-i*m_nDiskHeight);
char str[3];
itoa(DiskC[i],str,10);
pControlDC->SetBkMode(TRANSPARENT);
pControlDC->TextOut(cx-4,DOWN-i*m_nDiskHeight-1,str);
}
pWnd->ReleaseDC(pControlDC);
}
void CHanoiDlg::OnCancel()
{
CExitDlg exitdlg;
if(exitdlg.DoModal()!=IDOK)
{
return;
}
CDialog::OnCancel();
}
void CAboutDlg::OnBest()
{
CExitDlg exitdlg(NULL,FALSE);
exitdlg.DoModal();
}