MFC GUI 编程
description
Transcript of MFC GUI 编程
![Page 1: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/1.jpg)
MFC GUI 编程
![Page 2: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/2.jpg)
Greetings
![Page 3: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/3.jpg)
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!"; }
![Page 4: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/4.jpg)
void CGreetingsView::OnDraw(CDC* pDC) { CGreetingsDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);
RECT ClientRect; GetClientRect(&ClientRect); pDC->DrawText( pDoc->GetGreetings(),
-1, &ClientRect, DT_CENTER ); }
![Page 5: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/5.jpg)
Button void CGreetingsView::OnButtongreetings() { AfxMessageBox("Hello, world!"); }
![Page 6: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/6.jpg)
MiniDraw
![Page 7: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/7.jpg)
MiniDraw
用户可以画不同的图形元素 Line, rectangle, ellipse, polygon…
demo
![Page 8: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/8.jpg)
1. 用鼠标画线
![Page 9: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/9.jpg)
Member Variables class CMiniDrawView : public CView { private: int m_Dragging; CPoint m_PointOld; CPoint m_PointOrigin; }
CMiniDrawView::CMiniDrawView() { m_Dragging = 0; }
![Page 10: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/10.jpg)
响应消息 ClassWizard (^W)
![Page 11: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/11.jpg)
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); }
![Page 12: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/12.jpg)
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); }
![Page 13: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/13.jpg)
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); }
![Page 14: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/14.jpg)
Problem
窗口更新后线段消失了
原因? 没有存储数据
![Page 15: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/15.jpg)
2. 存储数据
![Page 16: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/16.jpg)
线段数据结构 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 ); } };
![Page 17: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/17.jpg)
保存线段的数组 class CMiniDrawView : public CView { vector<CLine *> m_LineArray; … }
#include <vector> using namespace std;
![Page 18: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/18.jpg)
保存线段数据 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 ); }
![Page 19: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/19.jpg)
重画所有线段 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); } }
![Page 20: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/20.jpg)
如何检测有无内存泄漏 Debug information
![Page 21: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/21.jpg)
释放空间 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;}}
![Page 22: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/22.jpg)
3. 更多图形元素 不同类型图形元素如何存储? 如何组织它们之间的关系?
![Page 23: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/23.jpg)
椭圆图形及数据结构 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 ); } };
![Page 24: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/24.jpg)
???
vector<CLine *> m_LineArray; vector<CEllipse *>
m_EllipseArray; …
![Page 25: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/25.jpg)
4. 父类和继承 class CFigure { public: virtual void Draw( CDC *pDC ) {} //虚函数
};
class CLine: public CFigure
class CEllipse: public CFigure
![Page 26: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/26.jpg)
5. 图形数组 class CMiniDrawView : public CView { vector<CFigure *> m_FigArray;
UINT m_CurrentTool; //图形类型 }
//数据初始化 CMiniDrawView::CMiniDrawView() { m_CurrentTool = ID_BUTTONLINE; }
替换m_LineArraym_FigArray CFigure *pFigure = NULL; pFigure = new CLine (m_PointOrigin.x, m_PointOrigin.y, point.x, point.y ); m_FigArray.push_back( pFigure );
![Page 27: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/27.jpg)
图形类型
void CMiniDrawView::OnButtonline() { m_CurrentTool = ID_BUTTONLINE; }
void CMiniDrawView::OnButtonellipse() { m_CurrentTool = ID_BUTTONELLIPSE; }
![Page 28: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/28.jpg)
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); }
![Page 29: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/29.jpg)
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); }
![Page 30: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/30.jpg)
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); } }
![Page 31: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/31.jpg)
线框画图模式 CMiniDrawView:: OnMouseMove() CMiniDrawView::OnLButtonUp()
CClientDC ClientDC( this ); ClientDC.SelectStockObject
(NULL_BRUSH); CMiniDrawView::OnDraw()
pDC->SelectStockObject (NULL_BRUSH);
![Page 32: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/32.jpg)
类的分离 Figure.h/cpp
![Page 33: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/33.jpg)
总结 STL vector GDI画图 鼠标交互 消息响应(鼠标) 按钮 类的继承和多态
![Page 34: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/34.jpg)
作业 3--MiniDraw 完善MiniDraw画图程序 写一个画图小程序MiniDraw,要求画直线
(Line),椭圆 (Ellipse),矩形 (Rectangle),多边形 (Polygon)等图形元素 ( 图元 )
每种图元需用一个类(对象)来封装,如CLine, CEllipse, CRect, CPolygon, CFreehand;
各种图元从一个父类 CFigure来继承; 学习类的继承和多态
![Page 35: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/35.jpg)
要求 至少完成直线 (Line),椭圆 (Ellipse),矩形 (Rectangle),多边形 (Polygon) ,自由手绘线 (Freehand)等图形元素
Deadline: 9:30a.m. April 6, 2011
![Page 36: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/36.jpg)
如何学好 VC
需要有好的 C/C++基础 理解Windows的消息机制,窗口句柄和其他 GUI句柄的含义和用途
多使用 Online Help 记住一些常用的消息名称和参数的意义 学会看别人的代码 多练习,在实践中成长!
![Page 37: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/37.jpg)
References
VC入门级书籍 Windows编程 《 MFC深入浅出》
![Page 38: MFC GUI 编程](https://reader034.fdocuments.us/reader034/viewer/2022042511/5681466b550346895db3909c/html5/thumbnails/38.jpg)
Q&A