附录5:七巧板程序 附录5:七巧板程序 / Example13-7:七巧板程序 #include ∥/拼板类 #define maX points #define ChIP Width 240 #define delta class CChip: public CObject DECLARE SERIAL (CChip) CPoint m pointList [MAX POINTS int m nPointCount bli CChipo( voidSetChip(int type, POINT *ppointlist, int count) void DrawChip(CDC *pDC) BOOLPt In Chip (point point) LPCRECT GetRect o void Move To(CSize offset voidSerialize(CArchive &ar) IMPLEMENT SERIAL (CChip, COb ject, 1) /设置拼图块参数 void CChip: SetChip (int type, POINT *ppointlist, int count m for (int i=0; i<count: i++)
附录 5:七巧板程序 372 附录 5: 七巧板程序 // Example 13-7: 七巧板程序 ////////////////////////////////// #include #include // 拼板类 //////////////////////////////////////////////////// #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(){} voidSetChip(int type, POINT *ppointlist, int count); voidDrawChip(CDC *pDC); BOOLPtInChip(POINT point); LPCRECT GetRect(); voidMoveTo(CSize offset); voidRotation(); voidSerialize(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++)
附录5:七巧板程序 m pointlist li]= ppointlistlil /绘出拼图块 void CChip: Draw Chip(CDC apDC CPen penNew, *ppenold CBrush brushNew, *pbrushold switch(m n Type) brushNew. CreateSolidBrush(RGB (127, 127, 127)) break brushNew. CreateSolidBrush(RGB(255, 0, 0)) 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 brushNew. CreateSolidBrush (RGB(127, 0, 127)) break case brushNew. CreateSolidBrush(RGB(0, 127, 127)) pen New CreatePen(PS SOLID, 1, RGB(o, 0, 0)) renold pDC->SelectObject(&penNew) pbrushold pDC->SelectObject(&brushNew)
附录 5:七巧板程序 373 m_pointList[i] = ppointlist[i]; } // 绘出拼图块 void CChip::DrawChip(CDC *pDC) { CPenpenNew, *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);
附录5:七巧板程序 pDC->Polygon(m pointList, m nPointCount) pDC->SelectObject(ppenold) pDC->SelectObject(pbrushold /检测一点是否在拼图块中 BOOL CChip: Pt In Chip (point point) rgn. CreatePolygonRgn(m pointList, m nPointCount, 0) return rgn. PtInRegion (point) /取拼图块的包含矩形 LPCRECT CChip: GetRect static rect rect rgn. CreatePolygonRgn(m pointList, m nPointCount, 0) rgn. GetRgnBox(&rect) rect right++ rect, bot tom++ return &rect /旋转拼图块 oid CChip: Rotation O CRgn rgn (m pointList, m nPoint Count, 0) double x=rect. left+rect. Width0/2;//计算旋转中心 double y= rect. toptrect Height(/2 double dx, dy: for (int i=0: i<m nPointCount: i++) /旋转各点
附录 5:七巧板程序 374 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++) // 旋转各点 {
附录5:七巧板程序 X-X dy =m pointList li. y-y m pointlist[].x=(int)(x+dx=*0. 707 1-dy*0. 7071) m pointlistlil.y =(int)(y+dx*0. 7071+dy*0. 707 /移动拼图块 void CChip: Move To( CSize offset) for (int i=0: i〉> m nPoint Count; for(int i=0; i>m pointList [il /文档类 #define chIp count 7 class CMy Doc public CDocument
附录 5:七巧板程序 375 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_nType; ar >> m_nPointCount; for(int i=0; i> m_pointList[i]; } } // 文档类 //////////////////////////////////////////////////// #define CHIP_COUNT 7 class CMyDoc : public CDocument {
附录5:七巧板程序 DECLARE DYNCREATE( CMyDoc CChip m chipList [CHIP COUNT public void Reset o virtual void Delete Contents virtual void Serialize( CArchive& ar IMPLEMENT DYNCREATE(CMy Doc, CDocument /初始化拼图块 void CMyDoc:: Reseto pOiNt pointList [MAX POINTS pointList [o]. x=DELTA pointList[o]y DEltA pointList[1]. x=DELTA+CHIP WIDTH pointList[l] y DELTA pointList[2]. x= DELTA+CHIP WIDTH/2 pointList [2] y DELTA+CHIP WIDTH/2 m chipList [o]. SetChip(1, pointList, 3) pointList[o]. x =DELTA pointlist[o]. y =DELTA pointList[l].x= DELTA pointList[l]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[o]. x= DELTA+CHIP WIDTH pointList[o]y= DELTA pointList[l].x= DELTA+CHIP WIDTH pointList[l] y= DELTA+CHIP WIDTH/2 pointList[2]. x= DELTA+(CHIP WIDTH*3)/4 pointList [2]y DELTA+CHIP WIDTH/4
附录 5:七巧板程序 376 DECLARE_DYNCREATE(CMyDoc) CChip m_chipList[CHIP_COUNT]; public: voidReset(); 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;
附录5:七巧板程序 m chipList[2]. Set Chip(, pointList, 3) pointList [o]. x =DELTA+CHIP WIDTH/2 pointList[o]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 [o]. x= DELTA+CHIP WIDTH pointList[o]y DELTA+CHIP WIDTH/2 pointList[l]. x= DELTA+CHIP WIDTH pointList[l]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[o]. x= DELTA+(CHIP WIDTH=*3)/4 pointList[o]y= DELTA+CHIP WIDTH/4 pointList[l]. x= DELTA+CHIP WIDTH/2 pointList[l] 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[o]. x=DELTA pointList[o]y= DELTA+CHIP WIDTH pointList[l].x= DELTA+CHIP WIDTH/4 pointList[l] y= DELTA+(CHIP WIDTH*3)/4 pointList[2]. x= DELTA+(CHIP WIDTH*3)/4 pointList[2] y DELTA+(CHIP WIDTH*3)/4
附录 5:七巧板程序 377 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;
附录5:七巧板程序 pointList[3]. x=DELTA+CHIP WIDTH/2 pointList[3]y DELTA+CHIP WIDTH m chipList [6]. Set Chip(7, pointList, 4) /清理文档:关闭文档、建立新文档和打开文档前调用 void CMy Doc: DeleteContentsO Reset CDocument:: Delete Contents ∥/系列化:读写文档时自动调用 void CMy Doc: Serialize(CArchive &a for (int i=0: i<CHIP COUNT; i++) m chipList[i]. Serialize(ar) ∥视图类 class CMyview: public Cview DECLARE DYNCREATE ( CMyView) BOOLm cAptured: CPoint m pointMouse int m nCurrIndex bli CMyViewOIm bCaptured FALSE: F CMy Doc* GetDocumento return (CMy Doc*)m pDocument virtual void OnInitialUpdate o virtual BOOL OnPreparePrinting(CPrintInfo* pInfo) virtual void OnDraw(CDC* pDC) afx msg void OnLButton Down (UINT nFlags, CPoint point) afx msg void OnLButtonUp UINT nFlags, CPoint point afx msg void On MouseMove UiNt nFlags, CPoint point) afx msg void OnRButton Down (UINT nFlags, CPoint point)
附录 5:七巧板程序 378 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) BOOLm_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);
附录5:七巧板程序 DECLARE MESSAGE MAP O IMPLEMENT DYNCREATE(CMy View, CView) BEGIN MESSAGE MAP(CMy View, CView) ON WM LBUTTONDOWN O ON WM LBUTTONUP O VEO ON WM RBUTTONDOWN O ON COMMAND (ID FILE PRINT, CView:: OnFilePrint ON COMMAND (ID FILE PRINT DIRECT, CView:: OnFilePrint ON COMMAND (ID FILE PRINT PREVIEW, CView:: OnFilePrintPreview) ND MESSAGE MAP O /更新初始化:当建立新文档或打开文档时调用 void CMyView: OnInitialUpdate o CView:: OnInitialUpdate o Invalidate /绘制视图:程序开始运行或窗体发生变化时自动调用 void CMyView: OnDraw(CDC* pDC) CMyDoc* pDoc Get o ASSERT VALID(pDoc) for(int i=0: im chiplist [i]. DrawChip(pDC) /消息响应:用户点击鼠标左键时调用 void CMyView:: OnLBut ton Down (UINT nFlags, CPoint point) CMyDoc* pDoc GetDocumento ASSERT VALID (pDoc) for(int i=CHIP COUNT-1: i>=0; i--) if(pDoc->m chipList[]. Pt InChip(point))
附录 5:七巧板程序 379 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::OnFilePrintPreview) END_MESSAGE_MAP() // 更新初始化:当建立新文档或打开文档时调用 void CMyView::OnInitialUpdate() { CView::OnInitialUpdate(); Invalidate(); } // 绘制视图:程序开始运行或窗体发生变化时自动调用 void CMyView::OnDraw(CDC* pDC) { CMyDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); for(int i=0; im_chipList[i].DrawChip(pDC); } // 消息响应:用户点击鼠标左键时调用 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)) {
附录5:七巧板程序 m cAptured TRUE m nturrindex break /释放鼠标左键 void CMyView:: OnLButtonUp qUINT nFlags, CPoint point) f(m cAptured) : ReleaseCapture o /移动鼠标左键 pid CMyView:: On Mouse Move (UINT nFlags, CPoint point) f(m cAptured) ASSERT VALID (pDoc) InvalidateRect(pDoc->m chipList [m nCurrIndex] GetRect O) CSize offset(point-m pointMouse pDoc->m chipList [m nCurrIndex] Move To(offset) InvalidateRect(pDoc->m chipList [m nCurrIndex] GetRect o) m pointMouse point pDoc->SetModifiedFlago /按下鼠标右键:旋转拼图块 void CMyView:: OnRButtonDown(UINT n Flags, CPoint point)
附录 5:七巧板程序 380 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)
附录5:七巧板程序 ly Doc* pDoc= GetDocumento ASSERT VALID(pDoc) for (int i=CHIP COUNT-1: i>=0: i--) f(pDoc->m chipList [i]. PtIn Chip(point)) InvalidateRect(pDoc->m chipList[i] Get O) Doc->m chipList[i]. Rotation o InvalidateRect (pDoc->m chipList [i]. GetRecto, FALSE) pDoc->SetModifiedFlagO break /准备打印:设置打印参数 BOOL CMyView:: On PreparePrinting(CPrintInfo* pInfo) pInfo->SetMaxPage(1) return DoPreparePrinting(pInfo) /主框架类 class CMainFrame public FRame Wnd DECLARE DYNCREATE(CMainFrame) IMPLEMENT DYNCREATE(CMainFrame, CFrame Wnd) /应用程序类 # define IDR MAINframe128主框架的资源代号 class CMyApp: public CWinApp public virtual BOOL InitInstance o DECLARE MESSAGE MAPO BEGIN MESSAGE MAP(CMyApp, CWinApp)
附录 5:七巧板程序 381 { 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_MAINFRAME 128 // 主框架的资源代号 class CMyApp : public CWinApp { public: virtual BOOL InitInstance(); DECLARE_MESSAGE_MAP() }; BEGIN_MESSAGE_MAP(CMyApp, CWinApp)