VC编程入门:MFC入门系列(六)
小标 2018-05-16 来源 : 阅读 939 评论 0

摘要:在VC编程入门中,我们今天讲一下图形设备接口(以下简称GDI),一个技术或语言的产生都有它的背景和原因。GDI是Windows提供的一套函数和结构,以便于我们调用它们来绘图。为什么要提供这样一个接口呢?接下来就让我们来学习下本次的VC编程入门吧。

    在VC编程入门中,我们今天讲一下图形设备接口(以下简称GDI),一个技术或语言的产生都有它的背景和原因。GDI是Windows提供的一套函数和结构,以便于我们调用它们来绘图。为什么要提供这样一个接口呢?接下来就让我们来学习下本次的VC编程入门吧。

  因为我们有不同的输出设备,各种显示器,各种打印机,他们有不同的打印驱动程序,也就是说,我们要针对不同的设备编程,要调用不同的设备驱动程序吗?那么,我的显示器换了,是不是我们的程序就要更换呢?我们并没有这样的麻烦,为什么呢?GDI提供这样一个平台,屏蔽了他们的差异。感觉就像Windows操作系统屏蔽了硬件,Java虚拟机屏蔽平台一样。我们使用的GDI全部使用设备上下文(DC)作为显示设备的信息来源。因此,我们无需关心设备的特性。

  在图形绘制当中,提供了一个叫做设备上下文(DC)的结构,是一个GDI提供的接口供我们来访问设备,所有的绘图都是通过设备上下文来进行。

  因此,同一应用程序可以在配有不同的类型显示器的计算机上使用。应用程序不需要针对所有显示器进行更改。

  为了后面的画图型准备,我们先添加一个菜单

  五个菜单的资源ID分别为ID_DRAW_LINE和ID_DRAW_RECT,
ID_DRAW_ROUND_RECT和ID_DRAW_CIRCLE和ID_DRAW_CURVE。
  添加好菜单,我们还要修改一下工具条,在OnCreateClient中,用下列代码修改原有的工具条代码
//工具条创建
UINTtool[]= {0,ID_DISPLAY_DOWN,ID_DISPLAY_UP,ID_DISPLAY_RIGHT,
ID_DISPLAY_LEFT,0,ID_DRAW_LINE,ID_DRAW_RECT,
ID_DRAW_ROUND_RECT,ID_DRAW_CIRCLE,ID_DRAW_CURVE};

//创建扩展风格的工具条
t.CreateEx(this,TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

   //工具条加载图片
   t.LoadBitmap(IDB_BITMAP1);
   //设置按钮
   t.SetButtons(tool,11);
   //工具条可以停靠在任何位置
   t.EnableDocking(CBRS_ALIGN_ANY);
   //框架接受任意停靠位置
      EnableDocking(CBRS_ALIGN_ANY);
   //执行停靠工具条
   DockControlBar(&t,AFX_IDW_DOCKBAR_TOP);

  在前面的基础之上,我们有添加了五个工具条按钮。再在消息映射中添加如下代码

  ON_COMMAND(ID_DRAW_LINE,line)
  ON_COMMAND(ID_DRAW_RECT,rect)
  ON_COMMAND(ID_DRAW_ROUND_RECT,round_rect)
  ON_COMMAND(ID_DRAW_CIRCLE,circle)
  ON_COMMAND(ID_DRAW_CURVE,curve)

  我们有消息映射,在添加消息映射处理函数

  void line()
  {
     ::MessageBox(0,"line","消息",MB_OK);
  }
  void rect()
  {
   ::MessageBox(0,"rect","消息",MB_OK);
  }
  void round_rect()
  {
   ::MessageBox(0,"round_rect","消息",MB_OK);
  }
  void circle()
  {
   ::MessageBox(0,"circle","消息",MB_OK);
  }
  void curve()
  {
   ::MessageBox(0,"curve","消息",MB_OK);
  }

2

  这时,我们的准备工作已做好。开始画图之前,我们还要讲一个概念——无效区域。我们知道,我们的显示器就是一块画布,我们切换窗口,显示器是不是要重新画一遍画布,这个问题要看情况。因为,画一遍画布(我们也叫重绘)是很费资源的,所以,我们就想要重绘一部分区域,我们如何知道要重绘那部分区域呢?我们将这个区域,设成要求重绘的矩形区域之后,重新绘制该区域。我们把这个区域称为无效区域。以后我们要重新绘制什么东东的时候,就可以将它设成无效区域。

  那么将这个区域设成了无效区域之后,谁来重新绘制它,如何绘制它呢?那么任何影响窗口的操作都会引发WM_PAINT消息,那么,谁来完成消息映射呢?是ON_WM_PAINT(),我们在消息映射要添加这一条,这个消息映射到了一个函数,这个函数是 OnPaint(),也就是说,我们的画图工作都在这里面完成。

  我们的目标先是画一条线出来,我们可以想象一下,我们先用鼠标点一下,就有一个起始点,鼠标不放开,拖动鼠标,会有一条线跟随,再点一下有了终止点,就可以画一条线了。我们要做的工作就是将上面的内容翻译成VC代码。

  我们要有两个点,还要一个重绘区域;所以我们再类sample中添加成员变量:

  CPoint NewPoint;//一个终止点
  CPoint OldPoint;//一个起始点
  RECT r;//需要刷新的矩形区域

  鼠标点下时,获得起始点:

  void OnLButtonDown(UINT i,CPoint p)//添加的消息处理函数
  {
    OldPoint=p;// 获得起始点
  }

  鼠标起来时,得到终止点,并绘一条线

  void OnLButtonUp(UINT i,CPoint p)
  {
     NewPoint=p;// 获得终止点
     //由起始点和终止点得到一个矩形
    r.left=OldPoint.x;
    r.top=OldPoint.y;
    r.right=NewPoint.x;
    r.bottom=NewPoint.y;
     //调用窗体的设置无效区域方法
    CWnd::InvalidateRect(&r,TRUE);
  }
  有了无效区域,我们再来绘图了:
  void OnPaint()
  {
        //设备上下文DC的创建,MFC将DC包装成了几个类,其中有类CPaintDC,
      CPaintDC d(this);
       //将坐标移动到起始点
      d.MoveTo(OldPoint);
      //绘制一条线
   d.LineTo(NewPoint);
  }

  这个时候,我们就可以试一下,我们自己做的画线程序了。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言VC/MFC频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程