VS2010/MFC/对话框程序
MFC练习
1.新建一个矩形类。 MoveDown(),MoveUp(),MoveLeft(),MoveRight()是移动的动作。int
position是表示该矩形当前的实际位置,按如下布局:
0 1 2
3 4 5
6 7 8
。MoveXXX()函数一是要判断是否可以响应,而是响应后要修改position的值与当前位置匹配。
如MoveUp()函数中,如果该矩形position为0,1,2,则应该不动(此判断也可省,在键盘响应处理中会根据空格所在位置指定唯一的矩形移动)。
class MyRect
{
public:
MyRect();
~MyRect();
//返回CRect对象
CRect getRect();
//初始化矩形
void setRect(int x1, int y1, int x2, int y2);
void MoveDown();
void MoveUp();
void MoveLeft();
void MoveRight();public:
int position;
private:
int x1;
int y1;
int x2;
int y2;
};
#include "stdafx.h"
#include "MyRect.h"MyRect::MyRect()
{
x1 = y1= x2= y2 = position = 0;
}MyRect::~MyRect()
{}
CRect MyRect::getRect()
{
CRect *rect = new CRect(x1, y1, x2, y2);
return *rect;
}void MyRect::setRect(int x1,int y1, int x2, int y2)
{
this->x1 = x1;
this->y1 = y1;
this->x2 = x2;
this->y2 = y2;
}void MyRect::MoveUp()
{
if (position == 0 || position == 1 || position ==2)
{
return;
}
else
{
y1 -= 100;
y2 -= 100;
position -= 3;
}
}void MyRect::MoveDown()
{
if (position == 6 || position == 7 || position == 8)
{
return;
}
else
{
y1 += 100;
y2 += 100;
position += 3;
}
}void MyRect::MoveLeft()
{
if (position == 0 || position == 3 || position == 6)
{
return;
}
else
{
x1 -= 100;
x2 -= 100;
position -= 1;
}
}void MyRect::MoveRight()
{
if (position == 2 || position == 5 || position == 8)
{
return;
}
else
{
x1 += 100;
x2 += 100;
position += 1;
}
}
2. 定义全局变量
struct MyPoint{
int x;
int y;
};
//端点位置
MyPoint point[9] = {0};//空格位置
static int BlankPos = 8;//矩形数组
MyRect *myrect[10];//填充画刷
CBrush *brush[10];
3. 初始化OnInitDialog()中
// TODO: 在此添加额外的初始化代码
//设置窗口大小,设置窗口居中
::SetWindowPos(this->m_hWnd,HWND_BOTTOM, 0, 0, 315, 338,SWP_NOZORDER);
CenterWindow();//初始化每个矩形的左上角点的坐标
for (int i = 0; i < 3; i++)
{
for (int j = 0; j <3; j++)
{
point[3*i+j].x = j * 100;
point[3*i+j].y = i * 100;
}
}
//初始化矩形和填充画刷
for (int i = 0; i < 8; i++)
{
myrect[i] = new MyRect();
myrect[i]->setRect(point[i].x, point[i].y, point[i].x+100, point[i].y+100);
myrect[i]->position = i;
brush[i] = new CBrush(RGB(rand()%255, rand()%255, rand()%255));
}
4. OnPaint()//
TODO: 在此添加额外的初始化代码 //创建自定义字体
CFont font;
font.CreateFont(20,20,0,0,FW_THIN,true,false,false,
CHINESEBIG5_CHARSET,OUT_CHARACTER_PRECIS,
CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,
FF_MODERN,"宋体");//客户区设备环境
CClientDC dc(this);
//新建画笔
CPen pen;
pen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
//选中字体
dc.SelectObject(pen);for (int i = 0; i < 8; i++)
{
//画矩形
dc.Rectangle(myrect[i]->getRect());
//填充矩形
dc.FillRect(myrect[i]->getRect(), brush[i]);
char num[10] = {‘0‘};
itoa(i+1, num, 10);
//设置文字背景透明
dc.SetBkMode(TRANSPARENT);
//选中字体
dc.SelectObject(font);
//写数字
dc.DrawText(num, -1, &myrect[i]->getRect(), DT_VCENTER|DT_CENTER|DT_SINGLELINE);
}//判断胜利
bool win = true;
for (int i = 0 ; i < 8; i++)
{
if (myrect[i]->position != i)
win = false;
}
if (win)
{
CString string;
string.Format("%s","你赢了!");
}
5. 键盘消息处理
添加KeyUp响应。根据空格所在位置BlankPos来对相应的矩形做处理。
对话框程序的KeyDown响应方向键无响应,需要做特殊处理。
void CRect9x9Dlg::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch(nChar)
{
case VK_LEFT:
if (BlankPos == 2 || BlankPos == 5 || BlankPos == 8)
{
break;
}
else
{
for (int i = 0 ; i < 8; i++)
if (myrect[i]->position == BlankPos+1)
{
myrect[i]->MoveLeft();
}
BlankPos += 1;
}
break;
case VK_UP:
if (BlankPos == 6 || BlankPos == 7 || BlankPos == 8)
{
break;
}
else
{
for (int i = 0 ; i < 8; i++)
if (myrect[i]->position == BlankPos + 3)
{
myrect[i]->MoveUp();
}
BlankPos += 3;
}
break;
case VK_RIGHT:
if (BlankPos == 0 || BlankPos == 3 || BlankPos == 6)
{
break;
}
else
{
for (int i = 0 ; i < 8; i++)
if (myrect[i]->position == BlankPos-1)
{
myrect[i]->MoveRight();
}
BlankPos -= 1;
}
break;
case VK_DOWN:
if (BlankPos == 0 || BlankPos == 1 || BlankPos == 2)
{
break;
}
else
{
for (int i = 0 ; i < 8; i++)
if (myrect[i]->position == BlankPos - 3)
{
myrect[i]->MoveDown();
}
BlankPos -= 3;
}
break;
default:
break;
}
Invalidate(TRUE);CDialogEx::OnKeyUp(nChar, nRepCnt, nFlags);
}