1 / 38

MFC GUI 编程

MFC GUI 编程. Greetings. Hello, World!. class CGreetingsDoc : public CDocument { protected: // create from serialization only char *m_pMessage; // Attributes public: char *GetGreetings() { return m_pMessage; } … } CGreetingsDoc::CGreetingsDoc() {

eshe
Download Presentation

MFC GUI 编程

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. MFC GUI 编程

  2. Greetings

  3. Hello, World! • class CGreetingsDoc : public CDocument • { • protected: // create from serialization only • char *m_pMessage; • // Attributes • public: • char *GetGreetings() • { • return m_pMessage; • } • … • } • CGreetingsDoc::CGreetingsDoc() • { • m_pMessage = "Hello, world!"; • }

  4. void CGreetingsView::OnDraw(CDC* pDC) • { • CGreetingsDoc* pDoc = GetDocument(); • ASSERT_VALID(pDoc); • RECT ClientRect; • GetClientRect(&ClientRect); • pDC->DrawText( pDoc->GetGreetings(), -1, &ClientRect, DT_CENTER ); • }

  5. Button • void CGreetingsView::OnButtongreetings() • { • AfxMessageBox("Hello, world!"); • }

  6. MiniDraw

  7. MiniDraw • 用户可以画不同的图形元素 • Line, rectangle, ellipse, polygon… • demo

  8. 1. 用鼠标画线

  9. Member Variables • class CMiniDrawView : public CView • { • private: • int m_Dragging; • CPoint m_PointOld; • CPoint m_PointOrigin; • } • CMiniDrawView::CMiniDrawView() • { • m_Dragging = 0; • }

  10. 响应消息 • ClassWizard (^W)

  11. WM_LBUTTONDOWN • void CMiniDrawView::OnLButtonDown(UINT nFlags, CPoint point) • { • //AfxMessageBox("button down"); • m_PointOrigin = point; • m_PointOld = point; • m_Dragging = 1; • CView::OnLButtonDown(nFlags, point); • }

  12. WM_MOUSEMOVE • void CMiniDrawView::OnMouseMove(UINT nFlags, CPoint point) • { • if( !m_Dragging ) • return; • CClientDC ClientDC( this ); • ClientDC.SetROP2( R2_NOT ); • ClientDC.MoveTo( m_PointOrigin ); • ClientDC.LineTo( m_PointOld ); • ClientDC.MoveTo( m_PointOrigin ); • ClientDC.LineTo( point ); • m_PointOld = point; • CView::OnMouseMove(nFlags, point); • }

  13. WM_LBUTTONUP • void CMiniDrawView::OnLButtonUp(UINT nFlags, CPoint point) • { • if( !m_Dragging ) • return ; • CClientDC ClientDC( this ); • ClientDC.SetROP2( R2_NOT ); • ClientDC.MoveTo( m_PointOrigin ); • ClientDC.LineTo( m_PointOld ); • ClientDC.SetROP2( R2_COPYPEN ); • ClientDC.MoveTo( m_PointOrigin ); • ClientDC.LineTo( point ); • m_Dragging = 0; • CView::OnLButtonUp(nFlags, point); • }

  14. Problem • 窗口更新后线段消失了 • 原因? • 没有存储数据

  15. 2. 存储数据

  16. 线段数据结构 • class CLine • { • private: • int m_X1, m_Y1, m_X2, m_Y2; • public: • CLine(int X1, int Y1, int X2, int Y2 ) • { • m_X1 = X1; • m_Y1 = Y1; • m_X2 = X2; • m_Y2 = Y2; • } • void Draw( CDC *pDC ) • { • pDC->MoveTo( m_X1, m_Y1 ); • pDC->LineTo( m_X2, m_Y2 ); • } • };

  17. 保存线段的数组 • class CMiniDrawView : public CView • { • vector<CLine *> m_LineArray; • … • } • #include <vector> • using namespace std;

  18. 保存线段数据 • void CMiniDrawView::OnLButtonUp(UINT nFlags, CPoint point) • { • // TODO: Add your message handler code here and/or call default • if( m_Dragging ) • { • CClientDC ClientDC( this ); • ClientDC.SetROP2( R2_NOT ); • ClientDC.MoveTo( m_PointOrigin ); • ClientDC.LineTo( m_PointOld ); • ClientDC.SetROP2( R2_COPYPEN ); • ClientDC.MoveTo( m_PointOrigin ); • ClientDC.LineTo( point ); • m_Dragging = 0; • CLine *pLine = NULL; • pLine = new CLine(m_PointOrigin.x, m_PointOrigin.y, • point.x, point.y ); • m_LineArray.push_back( pLine ); • }

  19. 重画所有线段 • void CMiniDrawView::OnDraw(CDC* pDC) • { • CMiniDrawDoc* pDoc = GetDocument(); • ASSERT_VALID(pDoc); • // TODO: add draw code for native data here • for( int i=0; i<m_LineArray.size(); i++) • { • m_LineArray.at(i)->Draw(pDC); • } • }

  20. 如何检测有无内存泄漏 • Debug information

  21. 释放空间 • CMiniDrawView::~CMiniDrawView() • { • for( int i=0; i<m_LineArray.size(); i++) • { • SAFEDELETE( m_LineArray.at(i) ); • } • } • #define SAFEDELETE(p) {if(p){delete p; p=NULL;}}

  22. 3. 更多图形元素 • 不同类型图形元素如何存储? • 如何组织它们之间的关系?

  23. 椭圆图形及数据结构 • class CEllipse • { • private: • int m_X1, m_Y1, m_X2, m_Y2; • public: • CEllipse(int X1, int Y1, int X2, int Y2 ) • { • m_X1 = X1; • m_Y1 = Y1; • m_X2 = X2; • m_Y2 = Y2; • } • void Draw( CDC *pDC ) • { • pDC->Ellipse( m_X1, m_Y1, m_X2, m_Y2 ); • } • };

  24. ??? • vector<CLine *> m_LineArray; • vector<CEllipse *> m_EllipseArray; • …

  25. 4. 父类和继承 • class CFigure • { • public: • virtual void Draw( CDC *pDC ) {} //虚函数 • }; • class CLine: public CFigure • class CEllipse: public CFigure

  26. 5. 图形数组 • class CMiniDrawView : public CView • { • vector<CFigure *> m_FigArray; • UINT m_CurrentTool; //图形类型 • } • //数据初始化 • CMiniDrawView::CMiniDrawView() • { • m_CurrentTool = ID_BUTTONLINE; • } • 替换m_LineArraym_FigArray • CFigure *pFigure = NULL; • pFigure = new CLine (m_PointOrigin.x, m_PointOrigin.y, • point.x, point.y ); • m_FigArray.push_back( pFigure );

  27. 图形类型 • void CMiniDrawView::OnButtonline() • { • m_CurrentTool = ID_BUTTONLINE; • } • void CMiniDrawView::OnButtonellipse() • { • m_CurrentTool = ID_BUTTONELLIPSE; • }

  28. OnMouseMove • void CMiniDrawView::OnMouseMove(UINT nFlags, CPoint point) • { • if( !m_Dragging ) • return ; • CClientDC ClientDC( this ); • ClientDC.SelectStockObject (NULL_BRUSH); • switch (m_CurrentTool) • { • case ID_BUTTONLINE: • ClientDC.SetROP2( R2_NOT ); • ClientDC.MoveTo( m_PointOrigin ); • ClientDC.LineTo( m_PointOld ); • ClientDC.MoveTo( m_PointOrigin ); • ClientDC.LineTo( point ); • break; • case ID_BUTTONELLIPSE: • ClientDC.SetROP2 (R2_NOT); • ClientDC.Ellipse (m_PointOrigin.x, m_PointOrigin.y, m_PointOld.x, m_PointOld.y ); • ClientDC.Ellipse (m_PointOrigin.x, m_PointOrigin.y, point.x, point.y ); • break; • } • m_PointOld = point; • CView::OnMouseMove(nFlags, point); • }

  29. OnLButtonUp • void CMiniDrawView::OnLButtonUp(UINT nFlags, CPoint point) • { • if( !m_Dragging ) • return; • CClientDC ClientDC( this ); • ClientDC.SelectStockObject (NULL_BRUSH); • CFigure *pFigure = NULL; • switch (m_CurrentTool) • { • case ID_BUTTONLINE: • ClientDC.SetROP2( R2_NOT ); • ClientDC.MoveTo( m_PointOrigin ); • ClientDC.LineTo( m_PointOld ); • pFigure = new CLine(m_PointOrigin.x, m_PointOrigin.y, • point.x, point.y ); • break; • case ID_BUTTONELLIPSE: • ClientDC.SetROP2 (R2_NOT); • ClientDC.Ellipse (m_PointOrigin.x, m_PointOrigin.y, m_PointOld.x, m_PointOld.y ); • pFigure = new CEllipse (m_PointOrigin.x, m_PointOrigin.y, point.x, point.y); • break; • } • ClientDC.SetROP2 (R2_COPYPEN); • pFigure->Draw (&ClientDC); • m_FigArray.push_back( pFigure ); • m_Dragging = 0; • CView::OnLButtonUp(nFlags, point); • }

  30. 6. 多态性 • void CMiniDrawView::OnDraw(CDC* pDC) • { • CMiniDrawDoc* pDoc = GetDocument(); • ASSERT_VALID(pDoc); • // TODO: add draw code for native data here • pDC->SelectStockObject (NULL_BRUSH); • for( int i=0; i<m_FigArray.size(); i++) • { • m_FigArray.at(i)->Draw(pDC); • } • }

  31. 线框画图模式 • CMiniDrawView:: OnMouseMove() • CMiniDrawView::OnLButtonUp() • CClientDC ClientDC( this ); • ClientDC.SelectStockObject (NULL_BRUSH); • CMiniDrawView::OnDraw() • pDC->SelectStockObject (NULL_BRUSH);

  32. 类的分离 • Figure.h/cpp

  33. 总结 • STL vector • GDI画图 • 鼠标交互 • 消息响应(鼠标) • 按钮 • 类的继承和多态

  34. 作业3--MiniDraw • 完善MiniDraw画图程序 • 写一个画图小程序MiniDraw,要求画直线(Line),椭圆(Ellipse),矩形(Rectangle),多边形(Polygon)等图形元素(图元) • 每种图元需用一个类(对象)来封装,如CLine, CEllipse, CRect, CPolygon, CFreehand; • 各种图元从一个父类CFigure来继承; • 学习类的继承和多态

  35. 要求 • 至少完成直线(Line),椭圆(Ellipse),矩形(Rectangle),多边形(Polygon) ,自由手绘线(Freehand)等图形元素 • Deadline: 9:30a.m. April 6, 2011

  36. 如何学好VC • 需要有好的C/C++基础 • 理解Windows的消息机制,窗口句柄和其他GUI句柄的含义和用途 • 多使用Online Help • 记住一些常用的消息名称和参数的意义 • 学会看别人的代码 • 多练习,在实践中成长!

  37. References • VC入门级书籍 • Windows编程 • 《MFC深入浅出》

  38. Q&A

More Related