类库大魔王
类库大魔王 懒惰,傲慢,以及无耐心

图形程序设计与实现

  这周开始投入环境组网绘图功能的Demo实现。说简单点,这就是一个图形编辑器,就像Visio之类的。以前也有过自己使用GDI画图形的经历,但那时更简单的一点,没有要求图形可以移动,所以实现时做的事更少些。虽然这次说是做Demo,但我为了以后能以这Demo为基础,继续实际项目的完全实现,在初期就做了不少事情,费了好些心思。
  首先是程序架构上,基本上是按照实际项目的设计来做的,以后也不用做大的修改和调整。界面上会有的元素,都留出位置了。花了近2天的时候,才把主界面的框架搭好。昨天又花了1天,把输入的数据源那部分功能也差不多完成了。今天才开始实现真正的绘图功能。
  这次Demo主要就是为了预研或显示绘图功能,所以这里需要投入的精力更多。项目使用MFC开发,不使用任何其他第三方的库,传统而显而易见的作法是在CView上进行绘制。本着尽量OO的原则,最先可以想到的是,每种图形元素,可以用一个独立的类来表示,而所有这些类,有一个公共的基类,在基类中声明接口。以前的设计中,我只是让每种图形类保存了各自的位置和类型信息,并实现一个绘图接口。这次我突然发现,如果把相应的响应用户操作也放到各个图形类中实现,才更合理。比如点住鼠标进行移动,这得让图形类自己决定自己该进行什么动作,像一般的矩形,就可以直接将整个矩形进行移动,像折线,则可能只是在中间的折点进行移动。于是一般说来,这些图形类应该能处理鼠标的按键按下,弹起,光标移动等事件。现在觉得这样的设计是理所当然的,可在以前,我是绝对想不到这点的,也确实曾经把这些操作都放到外面统一分类处理。而且自从知道了Loki::Factory这个模板类后,对于这种大批类的操作,我有种近乎执着的热情想让它们不被任何除了这工厂之外的其他模块知道,直至不知道它们的存在。有了这一批图形类后,就需要一个管理器来维护这些图形类实例化出来的对象。这个管理器完全将这些图形类实例的创建、销毁、任务分派等与界面(CView)隔离开来。对于界面来说,图形对象管理器可以完成所有功能。
  再说代码实现方面。这次专门看了一遍GDI+的SDK,准备试用一番,嗯,不算试用,是实际用上了。MFC中使用GDI+没有任何限制,在CView的OnDraw方法中把所有图形绘制一遍即可。当然也有双缓冲以免闪烁。网上的用GDI+实现双缓冲的文章和代码都很多,但一般说来只分两种:1、标准的GDI+做法,临时创建一个Gdiplus::Bitmap,将所有内容都画到这个Bitmap上,再将这个Bitmap画到设备上去;2、GDI风格的做法,先创建一个内存DC,GDI+都向这个内存DC画内容,最后将这内存DC都BitBlt到设备上。经过我的实验,发现第1种方法的资源消耗比较大,速度感觉上似乎也慢一点,但没具体测过,没实际数据来证明。于是我换用第2种做法,网上有一个很流行的CMemDC类,使用非常方便。但等我这样实现完后,发现移动某个图形时,需要刷新整个绘图区,还是会闪烁。上网随便搜索一下,发现一个很简单的解决办法:处理WM_ERASEBKGND消息,直接返回TRUE就可以了。

感觉本文不错,不妨小额鼓励我一下!
支付宝扫一扫

支付宝扫一扫

微信扫一扫

微信扫一扫

如果你看不到评论框,说明Disqus被墙了。