采用MFC编制MVC模式之球体演示程序

2016-01-29 12:00 97 1 收藏

采用MFC编制MVC模式之球体演示程序,采用MFC编制MVC模式之球体演示程序

【 tulaoshi.com - C语言心得技巧 】

采用 MFC 编制 MVC 模式之球体演示程序

作者:haykey

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)

下载源代码


  在传统面向过程的程序设计中,往往采用 Input-Processing-Output 模式,这“归功”于 DOS 操作系统的单任务。当 Windows 图形界面 OS 出现后,MVC(Model-View-Controller)模型更适合 Windows 图形界面程序的设计,它将数据处理和数据显示分离开,使维护,扩展系统更加灵活。其中,View:负责 显示数据,它从Model处获得数据然后显示。当然,一个Model会有用户可从不同角度来观察的多个View。Model:存储数据以及对数据进行各种运算和处理。Controller:负责接受用户输入,并且把用户输入转换成对 Model 的操作。因此Controller 可能会修改 Model 的数据,当数据修改后,更新 View。其结构示意图如下:




  一直采用MFC编程的朋友可能不太熟悉它,这是因为MFC的文档视图结构就是基于MVC的高层结构,这蒙蔽了我们的双眼。虽然MS替我们做了,我们还是有必要接触它,以在SDK or 其他地方有的放矢。我做了一个球体演示的例子,其界面如下:



  左侧两个表面积和体积Edit让使用者从文本的角度精确地观察,我们称其为TextView。右侧为从CStatic派生的CGraphicView,使得人们可直观地观察Sphere.对话窗口CMVCSphereDlg是控制器,来获取用户的键盘输入(输入半径后回车)和在Static上的鼠标点击与拖动(可动态调整球体半径并实时反馈球体变化)而CSphere类是模型,存储了球体半径和计算表面积,计算体积等处理半径数据的操作.
  现在让我们详细看看代码,来感受下Model,View,Controller之间如何关联,如何协同工作的。

class CSphere  {public:     ... ....    //更新Graphic-VIEW    BOOL UpdateGraphicView(HWND hWnd,const CRect &rect,BOOL bErase);    //更新Text-VIEW    void UpdateTextView();    //外界Controller的接口:设置球体半径    void SetRadius(float r);private:    //球体半径    float m_fRadius;    //计算球体表面积    float CalculateArea(float radius);    //计算球体体积    float CSphere::CalculateVolumn(float radius);};
  这里面 UpdateTextView,UpdateTextView 就是当用户输入新半径或拖动鼠标 Controller 捕获后通知 Model,Model 通知两个View更新显示。具体代码如下:
BOOL CSphere::UpdateGraphicView(HWND hWnd,const CRect &rect,BOOL bErase){    //data format examination    if(!::IsWindow(hWnd)||::IsRectEmpty(&rect))    {      AfxMessageBox("View is not created by now or rect is empty");      return false;    }    //get the window pointer from window handle    CWnd *pView = CWnd::FromHandle(hWnd);    if(pView == NULL)        return false;    //set graphic view''s radius in order to painting    ((CGraphicView*)pView)->SetRadius(m_fRadius);    bPaintSphere = true;//set paint tag true    //repaint    if(!::InvalidateRect(hWnd,&rect,bErase)&&   !::UpdateWindow(hWnd))    {      AfxMessageBox("UpdateView failed");      return true;    }        pView = NULL;    return false;}void CSphere::UpdateTextView(){   CMVCSphereDlg *parent = (CMVCSphereDlg *)AfxGetMainWnd();   CWnd *wnd1 = parent->GetDlgItem(IDC_SURFACE);   CWnd *wnd2 = parent->GetDlgItem(IDC_VOLUMN);      CString str;   str.Format("%.2f平方米",CalculateArea(m_fRadius));   wnd1->SetWindowText(str);   str.Empty();   str.Format("%.2f立方米",CalculateVolumn(m_fRadius));   wnd2->SetWindowText(str);}
CGraphicView中绘图关键代码如下:
void CGraphicView::OnPaint() {    ... .....    if(!bPaintSphere) dc.DrawText("球体演示",rect,DT_VCENTER|DT_CENTER|DT_SINGLELINE);    else{   int r=(int)m_radius;//半径取整   CPoint MiddlePoint = rect.CenterPoint();//以矩形框的中心为球心   int x=MiddlePoint.x;   int y=MiddlePoint.y;   oldpen = (CPen*)dc.SelectObject(&solid_pen);   oldbru = (CBrush*)dc.SelectObject(&brush);   dc.Ellipse(x-r,y-r,x+r,y+r);              //先画一个圆形          dc.SelectObject(&dash_pen);   dc.Arc(x-r/2,y-r,x+r/2,y+r,x,y-r,x,y+r);  //再画4个半圆弧   dc.Arc(x-r/2,y-r,x+r/2,y+r,x,y+r,x,y-r);   dc.Arc(x-r,y-r/2,x+r,y+r/2,x-r,y,x+r
                        

来源:http://www.tulaoshi.com/n/20160129/1484176.html

延伸阅读
首先我们说下通过鼠标的移动来绘制直线。 这里要捕获到鼠标的两个消息:WM_LBUTTONDOWN, WM_LBUTTONUP。响应WM_LBUTTONDOWN消息记录直线的起始点,响应WM_LBUTTONUP消息记录直线的终点并绘制直线。 好了,我们看看怎么响应。 void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) { //MessageBox("Left Button Clicks D...
MFC应用程序中指针的使用 作者:gouguijia 1) 在View中获得Doc指针 2) 在App中获得MainFrame指针 3) 在View中获得MainFrame指针 4) 获得View(已建立)指针 5) 获得当前文档指针 6) 获得状态栏与工具栏指针 7) 获得状态栏与工具栏变量 8) 在Mainframe获得菜单指针 9) ...
标签: Delphi
  在从事与财务相关的软件开发过程中,通常要求将小写金额转换成相应的大写金额,并打印在大写金额栏中。下面是用Delphi3.0编制的一个转换函数,能够方便的在程序中调用,并返回字符串。 1.定义函数num—str function num—str(ls: Variant): String; var dx—sz,dx—dw,str—int,str—dec,dx—str,f...
在非MFC程序中引用CString 作者:阿半 CString在当今软件设计界里还是小有名气的,说它是MFC中使用的最多的类一点也不过,然而在使用sdk编windows程序的时候,确不能利用CString类,只能用sdk的运行时库,比如strlen,strcpy,strstr等等,本文讨论的是在非mfc程序中使用CString类的方法,算是...
标签: PHP
PHP 世界中缓冲是一个热门的话题,因为 PHP 产生的动态页面,每次用户请求都需要重新计算,不论请求的结果是否一样,同时,PHP 每次都会编译一次脚本。这样的超负荷运转对一个流量很高的网站来说肯定难以忍受。幸运的是, Web 的结果可以缓冲,而不需要重新运行和编译脚本,商品化的产品像 ZendCache 或者开源的 Alternate PHP Ca...

经验教程

994

收藏

8
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部