第八章 文档/视图结构应用程序 8.1 文档/视图结构 8.2 图形与文字输出 8.3 定时器 8.4 鼠标和键盘消息处理 8.5 对话框 第八章 文档/视图结构应用程序 8.1 文档/视图结构 8.2 图形与文字输出 8.3 定时器 8.4 鼠标和键盘消息处理 8.5 对话框 8.6 菜单设计 8.7 程序举例
8.1 文档/视图结构 文档:用于管理应用程序的数据 视图:用户界面,用于显示、打印文档中的数据 管理与用户的交互。 数据的管理与显示分离的思想简化了开发过程 文档/视图结构应用程序: SDI MDI
【例8.1】在窗口中显示一个矩形框,框中显示“同舟共济 自强不息” 【例8.1】在窗口中显示一个矩形框,框中显示“同舟共济 自强不息” 工程名为 TEST BOOL CTESTDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here // (SDI documents will reuse this document) r=CRect(100,60,260,100); s="同舟共济 自强不息"; return TRUE; } 1. 生成SDI应用程序框架 2. 在CTESTDoc类中添加数据成员: public: CRect r; CString s; 3. 在文档类中对数据成员初始化
4. 在CTESTView类的OnDraw()函数添加代码: void CTESTView::OnDraw(CDC* pDC) { CTESTDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here pDC->Rectangle(pDoc->r); pDC->TextOut(110,70,pDoc->s); } 说明: (1)ClassView有5个类和1个全局对象: CAboutDlg类:about对话框类,由CDialog派生。 CMainFrame类:窗口框架类,由CFrameWnd派生 CTESTApp类:应用程序类,由CWinApp派生 CTESTDoc类:文档类,由CDocument派生 CTESTView类:视图类,由CView派生 theApp全局对象
(2)CRect描述一个矩形,有4个数据成员: left、top、right和bottom。 (3)GetDocument() 返回值指向当前文档的指针。 示例:CTESTDoc* pDoc= GetDocument(); 作用:让pDoc指向当前文档 (4)输出在OnDraw()中完成 pDC指向窗口中央的客户区对象 void CTESTView::OnDraw(CDC* pDC) { CTESTDoc* pDoc = GetDocument(); // 获得指向文档类对象的指针 ASSERT_VALID(pDoc); // 检查pDoc是否有效,若无效结束程序 // TODO: add draw code for native data here } (5) OnDraw()的调用 自动调用:当窗口发生变化时 手工调用:调用Invalidate()和InvalidateRect()函数时 Invalidate(TRUE) //擦除窗口原有的内容,重新绘制。 Invalidate(FALSE) //窗口原有的内容保留,再进行绘制。 InvalidateRect(矩形, TRUE) //重新绘制这个矩形区域。 InvalidateRect(矩形, FALSE) //原有内容保留,再绘制矩形区域。
BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount); (2)画点 (1)文字输出 BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount); (2)画点 COLORREF SetPixel(int x, int y, COLORREF crColor); COLORREF SetPixel(POINT point, COLORREF crColor); 说明: 例如: COLORREF C1=RGB(0, 0, 0)) //合成黑色 COLORREF C2=RGB(255, 0, 0)) //合成红色 COLORREF C3=RGB(255, 255, 0)) //合成黄色 COLORREF C4=RGB(255, 255, 255)) //合成白色 POINT:MFC的结构类型,表示平面上的一个点, 数据成员是x和y COLORREF:32位整数类型,表示颜色 COLORREF C1=RGB(0, 0, 0)) //合成黑色 COLORREF C2=RGB(255, 0, 0)) //合成红色 COLORREF C4=RGB(255, 255, 255)) //合成白色
(3)画线 起点: CPoint MoveTo(int x,int y); CPoint MoveTo(POINT point); 终点: BOOL LineTo(int x, int y); BOOL LineTo(POINT point); (4)画矩形 BOOL Rectangle(int x1, int y1, int x2, int y2); BOOL Rectangle(LPCRECT lpRect); (5)画椭圆 BOOL Ellipse(int x1, int y1, int x2, int y2); BOOL Ellipse(LPCRECT lpRect); (6)获取客户区的大小 void GetClientRect( LPRECT lpRect ) const;
【例8.2】改变窗口时,矩形框和文字总是显示在窗口的中央 void CTESTView::OnDraw(CDC* pDC) { CTESTDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CRect a,b; int w=160; int h=40; GetClientRect(&a); b.left=(a.Width()-w)/2; b.top=(a.Height()-h)/2; b.right=b.left+w; b.bottom=b.top+h; pDC->Rectangle(b); pDC->TextOut(b.left+10,b.top+10,"同舟共济、自强不息!"); }
【例8.3】绘制-2π~2π之间的sin曲线。 在TEST.CPP中添加命令: #include "math.h" void CTESTView::OnDraw(CDC* pDC) { CTESTDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CRect rect; GetClientRect(rect); int x0=rect.Width()/2; int y0=rect.Height()/2; pDC->MoveTo(20,y0); pDC->LineTo(rect.Width()-20,y0); pDC->MoveTo(x0,20); pDC->LineTo(x0,rect.Height()-20); double step=3.14159/100; for(int i=-200;i<200;i++ ) pDC->SetPixel(x0+(i/300.0)*rect.Width()/2,y0-sin(step*i)*rect.Height()/4,RGB(255,0,0)); }