关于一个mfc的程序

may-night 2018-02-22 04:36:58
这是一个七巧板拼图的代码,先上代码:

#include<afxwin.h>
#include<afxext.h>
#include<resource.h>
//拼版类//////////////////////////////////////
#define MAX_POINTS 4
#define CHIP_WIDTH 240
#define DELTA 30
class CChip:public CObject
{
DECLARE_SERIAL(CChip)
int m_nType;
CPoint m_pointList[MAX_POINTS];
int m_nPointCount;
public:
CChip() {}
void SetChip(int type, POINT *ppointlist, int count);
void DrawChip(CDC *pDC);
BOOL PtInChip(POINT point);
LPCRECT GetRect();
void MoveTo(CSize offset);
void Rotation();
void Serialize(CArchive &ar);

};

IMPLEMENT_SERIAL(CChip,CObject,1)
void CChip::SetChip(int type,POINT *ppointlist,int count) //设置拼图块参数
{
m_nType=type;
m_nPointCount=count;
for(int i=0;i<count;i++)
m_pointList[i]=ppointlist[i];
}

void CChip::DrawChip(CDC *pDC) //绘出拼图块
{
CPen penNew,*ppenOld;
CBrush brushNew,*pbrushOld;
switch(m_nType){
case 1:
brushNew.CreateSolidBrush(RGB(127,127,127));
break;
case 2:
brushNew.CreateSolidBrush(RGB(255,0,0));
break;
case 3:
brushNew.CreateSolidBrush(RGB(0,255,0));
break;
case 4:
brushNew.CreateSolidBrush(RGB(0,0,255));
break;
case 5:
brushNew.CreateSolidBrush(RGB(127,127,0));
break;
case 6:
brushNew.CreateSolidBrush(RGB(127,0,127));
break;
case 7:
brushNew.CreateSolidBrush(RGB(0,127,127));
break;

}
penNew.CreatePen(PS_SOLID,1,RGB(0,0,0));
ppenOld=pDC->SelectObject(&penNew);
pbrushOld=pDC->SelectObject(&brushNew);
pDC->Polygon(m_pointList,m_nPointCount);
pDC->SelectObject(ppenOld);
pDC->SelectObject(pbrushOld);
}

BOOL CChip::PtInChip(POINT point) //检测一点是否在拼图块中
{
CRgn rgn;
rgn.CreatePolygonRgn(m_pointList,m_nPointCount,0);
return rgn.PtInRegion(point);
}

LPCRECT CChip::GetRect() //取拼图块的包含矩形
{
static RECT rect;
CRgn rgn;
rgn.CreatePolygonRgn(m_pointList,m_nPointCount,0);
rgn.GetRgnBox(&rect);
rect.right++;
rect.bottom++;
return ▭
}

void CChip::Rotation() //旋转拼图块
{
CRect rect;
CRgn rgn;
rgn.CreatePolygonRgn(m_pointList,m_nPointCount,0);
rgn.GetRgnBox(&rect);
double x=rect.left+rect.Width()/2; //计算旋转中心
double y=rect.top+rect.Height()/2;
double dx,dy;
for(int i=0;i<m_nPointCount;i++) //旋转各点
{
dx=m_pointList[i].x-x;
dy=m_pointList[i].y-y;
m_pointList[i].x=(int)(x+dx*0.7071-dy*0.7071);
m_pointList[i].y=(int)(y+dx*0.7071+dy*0.7071);
}
}

void CChip::MoveTo(CSize offset) //移动拼图块
{
for(int i=0;i<m_nPointCount;i++)

m_pointList[i]=m_pointList[i]+offset;
}

void CChip::Serialize(CArchive &ar) //序列化
{
if(ar.IsStoring())
{
ar<<m_nType;
ar<<m_nPointCount;
for(int i=0;i<m_nPointCount;i++)
{
ar<<m_pointList[i];
}
}else
{
ar>>m_nType;
ar>>m_nPointCount;
for(int i=0;i<m_nPointCount;i++)
{
ar>>m_pointList[i];
}

}
}


//文档类//////////////////////////////////////
#define CHIP_COUNT 7
class CMyDoc:public CDocument
{
DECLARE_DYNCREATE(CMyDoc)
CChip m_chipList[CHIP_COUNT];
public:
void Reset();
virtual void DeleteContents();
virtual void Serialize(CArchive& ar);
};

IMPLEMENT_DYNCREATE(CMyDoc,CDocument)
void CMyDoc::Reset() //初始化拼图块
{
POINT pointList[MAX_POINTS];
pointList[0].x=DELTA;
pointList[0].y=DELTA;
pointList[1].x=DELTA+CHIP_WIDTH;
pointList[1].y=DELTA;
pointList[2].x=DELTA+CHIP_WIDTH/2;
pointList[2].y=DELTA+CHIP_WIDTH/2;
m_chipList[0].SetChip(1,pointList,3);
pointList[0].x=DELTA;
pointList[0].y=DELTA;
pointList[1].x=DELTA;
pointList[1].y=DELTA+CHIP_WIDTH;
pointList[2].x=DELTA+CHIP_WIDTH/2;
pointList[2].y=DELTA+CHIP_WIDTH/2;
m_chipList[1].SetChip(2,pointList,3);
pointList[0].x=DELTA+CHIP_WIDTH;
pointList[0].y=DELTA;
pointList[1].x=DELTA+CHIP_WIDTH;
pointList[1].y=DELTA+CHIP_WIDTH/2;
pointList[2].x=DELTA+(CHIP_WIDTH*3)/4;
pointList[2].y=DELTA+CHIP_WIDTH/4;
m_chipList[2].SetChip(3,pointList,3);
pointList[0].x=DELTA+CHIP_WIDTH/2;
pointList[0].y=DELTA+CHIP_WIDTH/2;
pointList[1].x=DELTA+CHIP_WIDTH/4;
pointList[1].y=DELTA+(CHIP_WIDTH*3)/4;
pointList[2].x=DELTA+(CHIP_WIDTH*3)/4;
pointList[2].y=DELTA+(CHIP_WIDTH*3)/4;
m_chipList[3].SetChip(4,pointList,3);
pointList[0].x=DELTA+CHIP_WIDTH;
pointList[0].y=DELTA+CHIP_WIDTH/2;
pointList[1].x=DELTA+CHIP_WIDTH;
pointList[1].y=DELTA+CHIP_WIDTH;
pointList[2].x=DELTA+CHIP_WIDTH/2;
pointList[2].y=DELTA+CHIP_WIDTH;
m_chipList[4].SetChip(5,pointList,3);
pointList[0].x=DELTA+(CHIP_WIDTH*3)/4;
pointList[0].y=DELTA+CHIP_WIDTH/4;
pointList[1].x=DELTA+CHIP_WIDTH/2;
pointList[1].y=DELTA+CHIP_WIDTH/2;
pointList[2].x=DELTA+(CHIP_WIDTH*3)/4;
pointList[2].y=DELTA+(CHIP_WIDTH*3)/4;
pointList[3].x=DELTA+CHIP_WIDTH;
pointList[3].y=DELTA+CHIP_WIDTH/2;
m_chipList[5].SetChip(6,pointList,4);
pointList[0].x=DELTA;
pointList[0].y=DELTA+CHIP_WIDTH;
pointList[1].x=DELTA+CHIP_WIDTH/4;
pointList[1].y=DELTA+(CHIP_WIDTH*3)/4;
pointList[2].x=DELTA+(CHIP_WIDTH*3)/4;
pointList[2].y=DELTA+(CHIP_WIDTH*3)/4;
pointList[3].x=DELTA+CHIP_WIDTH/2;
pointList[3].y=DELTA+CHIP_WIDTH;
m_chipList[6].SetChip(7,pointList,4);
}

void CMyDoc::DeleteContents() //清理文档:关闭文档、建立新文档和打开文档前调用
{
Reset();
CDocument::DeleteContents();
}

void CMyDoc::Serialize(CArchive &ar) //系列化:读写文档时自动调用
{
for(int i=0;i<CHIP_COUNT;i++)
{
m_chipList[i].Serialize(ar);
}
}

//视图类//////////////////////////////////////
class CMyView:public CView
{
DECLARE_DYNCREATE(CMyView)
BOOL m_bCaptured;
CPoint m_pointMouse;
int m_nCurrIndex;
public:
CMyView(){m_bCaptured=FALSE;}
CMyDoc* GetDocument(){return (CMyDoc*)m_pDocument;}
virtual void OnInitialUpdate();
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnDraw(CDC* pDC);
afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
afx_msg void OnLButtonUp(UINT nFlags,CPoint point);
afx_msg void OnMouseMove(UINT nFlags,CPoint point);
afx_msg void OnRButtonDown(UINT nFlags,CPoint point);
DECLARE_MESSAGE_MAP()
};

IMPLEMENT_DYNCREATE(CMyView,CView)
BEGIN_MESSAGE_MAP(CMyView,CView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONDOWN()
ON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT,CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrint)
END_MESSAGE_MAP()
void CMyView::OnInitialUpdate() //更新初始化:当建立新文档或打开文档时调用
{
CView::OnInitialUpdate();
Invalidate();
}

void CMyView::OnDraw(CDC* pDC) //绘制视图:程序开始运行或窗体发生变化时自动调用
{
CMyDoc* pDoc=GetDocument();
ASSERT_VALID(pDoc);
for(int i=0;i<CHIP_COUNT;i++)
{
pDoc->m_chipList[i].DrawChip(pDC);
}
}

void CMyView::OnLButtonDown(UINT nFlags,CPoint point) //消息响应:用户点击鼠标左键时调用
{
CMyDoc* pDoc=GetDocument();
ASSERT_VALID(pDoc);
for(int i=0;i<CHIP_COUNT;i++)
{
if(pDoc->m_chipList[i].PtInChip(point))
{
SetCapture();
m_bCaptured=TRUE;
m_pointMouse=point;
m_nCurrIndex=i;
break;
}
}
}

void CMyView::OnLButtonUp(UINT nFlags,CPoint point) //释放鼠标左键
{
if(m_bCaptured)
{
::ReleaseCapture();
m_bCaptured=FALSE;
}
}


void CMyView::OnMouseMove(UINT nFlags,CPoint point) //移动鼠标左键
{
if(m_bCaptured)
{
CMyDoc* pDoc=GetDocument();
ASSERT_VALID(pDoc);
InvalidateRect(pDoc->m_chipList[m_nCurrIndex].GetRect());
CSize offset(point-m_pointMouse);
pDoc->m_chipList[m_nCurrIndex].MoveTo(offset);
InvalidateRect(pDoc->m_chipList[m_nCurrIndex].GetRect());
m_pointMouse=point;
pDoc->SetModifiedFlag();
}
}

void CMyView::OnRButtonDown(UINT nFlags,CPoint point) //按下鼠标右键:旋转拼图块
{
CMyDoc* pDoc=GetDocument();
ASSERT_VALID(pDoc);
for(int i=CHIP_COUNT-1;i>=0;i--)
if(pDoc->m_chipList[i].PtInChip(point))
{InvalidateRect(pDoc->m_chipList[i].GetRect());
pDoc->m_chipList[i].Rotation();
InvalidateRect(pDoc->m_chipList[i].GetRect(),FALSE);
pDoc->SetModifiedFlag ();
break;
}
}
BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo)
{
pInfo->SetMaxPage(1);
return DoPreparePrinting(pInfo);
}
//主框架类
class CMainFrame:public CFrameWnd
{
DECLARE_DYNCREATE(CMainFrame)};
IMPLEMENT_DYNCREATE(CMainFrame,CFrameWnd)
//应用程序类
#define IDR_MAINFRME 128
class CMyApp:public CWinApp

{public:
virtual BOOL InitInstance();
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CMyApp,CWinApp)
ON_COMMAND(ID_FILE_NEW,CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN,CWinApp::OnFileOpen)
ON_COMMAND(ID_FILE_PRINT_SETUP,CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP();
BOOL CMyApp::InitInstance()
{
CSingleDocTemplate* pDocTemplate;
pDocTemplate=new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMyDoc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CMyView));
AddDocTemplate(pDocTemplate);
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if(!ProcessShellCommand(cmdInfo))
return FALSE;
m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);
return TRUE;
}
CMyApp theApp;
现在程序是能运行但是一旦点击就报错 希望能帮忙解决一下 谢谢
...全文
896 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2018-03-12
  • 打赏
  • 举报
回复
move(int x,int y) x;y 是应该是增量, 增量 应该有 + - 你 怎么 计算的 ? 参考 Reset 函数 !
may-night 2018-03-12
  • 打赏
  • 举报
回复
引用 37 楼 schlafenhamster 的回复:
CChip 类少个 m_Color,以至于 void CChip::DrawChip(CDC *pDC) 时 颜色 依赖 实例 ,即 switch 。这种方法 不好,
这个程序不算严谨 主要是想看看他的功能如何实现
schlafenhamster 2018-03-12
  • 打赏
  • 举报
回复
CChip 类少个 m_Color,以至于 void CChip::DrawChip(CDC *pDC) 时 颜色 依赖 实例 ,即 switch 。这种方法 不好,
may-night 2018-03-12
  • 打赏
  • 举报
回复
引用 35 楼 u011342949 的回复:
[quote=引用 34 楼 schlafenhamster 的回复:] move(int x,int y) x;y 是应该是增量, 增量 应该有 + - 你 怎么 计算的 ? 参考 Reset 函数 !
x+=1不是等价于x=x+1么? 如果语法有问题的话 那应该连x方向都无法移动了吧[/quote] 我发现问题了 我的疏忽 for循环没加大括号..
may-night 2018-03-12
  • 打赏
  • 举报
回复
引用 34 楼 schlafenhamster 的回复:
move(int x,int y) x;y 是应该是增量, 增量 应该有 + - 你 怎么 计算的 ? 参考 Reset 函数 !
x+=1不是等价于x=x+1么? 如果语法有问题的话 那应该连x方向都无法移动了吧
may-night 2018-03-11
  • 打赏
  • 举报
回复
引用 31 楼 schlafenhamster 的回复:
ChangeOrder 调用结果:m_nType 0-bottom 6=top 1,3,4,5,6,7,2 1,3,4,6,7,2,5 3,4,6,7,2,5,1 4,6,7,2,5,1,3 4,7,2,5,1,3,6 7,2,5,1,3,6,4 2,5,1,3,6,4,7
汗颜...我在做一个按一个按钮然后图形变成一个固定图形的时候发现Moveto这个函数只有一个方向能移动 然后我新定义了一个函数 发现还是只有一个方向
void CChip::move(int x,int y)			//移动拼图块
{
	for(int i=0;i<m_nPointCount;i++)
	
		m_pointList[i].x+=x;
	     m_pointList[i].y+=y;
	}

may-night 2018-03-11
  • 打赏
  • 举报
回复
引用 31 楼 schlafenhamster 的回复:
ChangeOrder 调用结果:m_nType 0-bottom 6=top 1,3,4,5,6,7,2 1,3,4,6,7,2,5 3,4,6,7,2,5,1 4,6,7,2,5,1,3 4,7,2,5,1,3,6 7,2,5,1,3,6,4 2,5,1,3,6,4,7
非常感谢,马上研究一下~~
schlafenhamster 2018-03-09
  • 打赏
  • 举报
回复
ChangeOrder 调用结果:m_nType 0-bottom 6=top 1,3,4,5,6,7,2 1,3,4,6,7,2,5 3,4,6,7,2,5,1 4,6,7,2,5,1,3 4,7,2,5,1,3,6 7,2,5,1,3,6,4 2,5,1,3,6,4,7
schlafenhamster 2018-03-09
  • 打赏
  • 举报
回复
给你 写了一个:

//
void CMyDoc::ChangeOrder(int newChip)
{
	BOOL start=FALSE;
	CChip Chip;
	int i=0;
	int j=0;
//
	if(newChip == m_chipList[TOP_CHIP].m_nType) return;
//
	for (i=0;i<TOP_CHIP; i++)
	{
		if(newChip == m_chipList[i].m_nType)
		{// first
			Chip.m_nType=m_chipList[i].m_nType;
			Chip.m_nPointCount=m_chipList[i].m_nPointCount;
			for(j=0;j<Chip.m_nPointCount;j++)
			{
				Chip.m_pointList[j]=m_chipList[i].m_pointList[j];
			}
			start=TRUE;
		}
		if(start)
		{// swap 
			m_chipList[i].m_nType=m_chipList[i+1].m_nType;
			m_chipList[i].m_nPointCount=m_chipList[i+1].m_nPointCount;
			for(j=0;j<m_chipList[i].m_nPointCount;j++)
			{
				m_chipList[i].m_pointList[j]=m_chipList[i+1].m_pointList[j];
			}
		}
		afxDump << m_chipList[i].m_nType << ",";
	}
// last
	afxDump << Chip.m_nType << "\n";
	m_chipList[TOP_CHIP].m_nType=Chip.m_nType;
	m_chipList[TOP_CHIP].m_nPointCount=Chip.m_nPointCount;
	for(j=0;j<Chip.m_nPointCount;j++)
	{
		m_chipList[TOP_CHIP].m_pointList[j]=Chip.m_pointList[j];
	}
}
调用:
void CMyView::OnLButtonDown(UINT nFlags,CPoint point)
{
	CMyDoc* pDoc=GetDocument();
	ASSERT_VALID(pDoc);
//
	for(int i=CHIP_COUNT-1;i>=0;i--)
	{
		if(pDoc->m_chipList[i].PtInChip(point))
		{// 
			SetCapture();
			m_bCaptured=TRUE;
			m_pointMouse=point;
			pDoc->ChangeOrder(pDoc->m_chipList[i].m_nType);
			Invalidate();
			break;
		}
	}
}
//
void CMyView::OnRButtonDown(UINT nFlags,CPoint point) //按下鼠标右键:旋转拼图块
{
	CMyDoc* pDoc=GetDocument();
	ASSERT_VALID(pDoc);
//
	for(int i=CHIP_COUNT-1;i>=0;i--)
	{
		if(pDoc->m_chipList[i].PtInChip(point))
		{
			pDoc->m_chipList[i].Rotation();
			pDoc->ChangeOrder(pDoc->m_chipList[i].m_nType);
			Invalidate();
//			pDoc->SetModifiedFlag();
			break; 
		}
	}
}

#define CHIP_COUNT 7
#define TOP_CHIP CHIP_COUNT-1

schlafenhamster 2018-03-08
  • 打赏
  • 举报
回复
概念上 就是类似窗口 Z order 的问题。 Onpaint 要 按 当前 order 来 绘制,0 是 bottom ,6 是 top 也就是 当前的 selection。
may-night 2018-03-08
  • 打赏
  • 举报
回复
引用 27 楼 schlafenhamster 的回复:
当 chips 重叠 时 你看看 被选中的 chip(点击) 能不能 在 上面 显示?
明白您的意思了 昨天在改功能的时候正好发现这点了2333
schlafenhamster 2018-03-07
  • 打赏
  • 举报
回复
当 chips 重叠 时 你看看 被选中的 chip(点击) 能不能 在 上面 显示?
may-night 2018-03-06
  • 打赏
  • 举报
回复
引用 25 楼 schlafenhamster 的回复:
一个 问题是 被 选择 的 chip 不在 上面 而 在 下面 !
不是很能明白您的意思
may-night 2018-03-05
  • 打赏
  • 举报
回复
引用 23 楼 schlafenhamster 的回复:
CButton* m_pBtns[5];// 应该在 .h 里 定义
好的 非常感谢
schlafenhamster 2018-03-05
  • 打赏
  • 举报
回复
一个 问题是 被 选择 的 chip 不在 上面 而 在 下面 !
schlafenhamster 2018-03-04
  • 打赏
  • 举报
回复
CButton* m_pBtns[5];// 应该在 .h 里 定义
may-night 2018-03-04
  • 打赏
  • 举报
回复
引用 21 楼 schlafenhamster 的回复:
例如toolbar 加 reset void CMainFrame::OnButton32771() { // TODO: Add your command handler code here CMyDoc *pDoc=(CMyDoc*)GetActiveDocument(); pDoc->Reset(); Invalidate(); }
我是网上摸索着搞了一个 void CMyView::OnInitialUpdate() //更新初始化:当建立新文档或打开文档时调用 { CView::OnInitialUpdate(); Invalidate(); //按钮 CButton* btn = new CButton[5]; DWORD dwStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON; btn[1].Create(_T("动态按钮"), dwStyle,CRect(380,400,450+80,450),this,IDC_D_BTN); }
may-night 2018-03-02
  • 打赏
  • 举报
回复
引用 19 楼 schlafenhamster 的回复:
"但是我想的是类似于对话框的那种按钮" 可以在 view 中(客户区) 动态 创建一个 按钮。
好的 我试一下 谢谢
schlafenhamster 2018-03-02
  • 打赏
  • 举报
回复
例如toolbar 加 reset void CMainFrame::OnButton32771() { // TODO: Add your command handler code here CMyDoc *pDoc=(CMyDoc*)GetActiveDocument(); pDoc->Reset(); Invalidate(); }
schlafenhamster 2018-03-01
  • 打赏
  • 举报
回复
"但是我想的是类似于对话框的那种按钮" 可以在 view 中(客户区) 动态 创建一个 按钮。
加载更多回复(18)

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧