MFC 多视图同步画图解决方案

 今天看《深入浅出MFC》时,看到要做多视图同步画图问题,此书上刚介绍完单视图画图后,引出多视图画图的问题(多视图是指一个子视图窗口中多个视图区域,由SpliiterWnd分割生成的)。存在相互通知,并特别强调绘图效率的问题。我迫不及待的用自己的想法实现了这个高效率绘图问题。后来看了一下书上的方法,确实也不错,但感觉比我的绘图效率低。我的绘图方法其实是因为书上开始讲的单视图绘图的方法,给了我一个用此方法来提高绘图效率的灵感。

 

单视图画图的基本方法交代:

1:通过CStroke类(派生于COjbect,以实现序列化),记录一次笔画的所有点信息,以及笔画宽度,并完成相应绘画工作(笔画就是鼠标左键按下,画图,到左键松开)。

 

2:Doc通过建立CObList,来保存本次绘画的所有笔画。在保存文件时进行序列化。

3:View的OnDraw函数通过遍历CObList的每个对象,完成所有笔画的现实工作。

4:直接通过OnLButtonDown,OnLButtonUp,OnMouseMove即时来完成绘图,并在此保存笔画信息。

 

就是因为第4点,让我想到一个高效率绘图方法。

 

首先介绍书上的方法:

书上采用UpdateAllView函数通知其他子视图其他视图进行重画,因为UpdateAllView引发子视图调用OnUpdate,然后在OnUpdate里面利用UpdateAllView传递过来的pHint来设定所需重画的最小矩形区域。以提高绘画效率。

 

这里我需要说明:为什么要提高绘画效率,因为传统的方法是通过UpdateAllViews来通知子视图重画全部区域,但设想要实现即时绘画,鼠标移动的消息可是很多啊,如果在这个情况下不断地UpdateAllViews 可想屏幕会多卡。

 

而我的思路是:基本可以概括为,发送相同消息给兄弟视图,让兄弟视图利用OnLButtonDown,OnLButtonUp,OnMouseMove里本身的即时绘图来实现即时绘画。

思路简介//
用CStroke类记录一次笔画过程中的点,以及点所对应的线的粗度                                                                                     
由当前(激活的)视图负责点记录,并向其他兄弟视图发送相同消息(带有nFlags标记),来使得其它子视图是负责                  
当前(激活的)视图在自己鼠标消息中绘画。                                                                                                               

///其他视图通过nFlags标记位判断此消息是兄弟视图发送的消息,还是windows发送的消息以区别对待。如果是兄弟消息那么就不 ///

用保存绘画信息(因为绘画信息只保留一份就可以,由当前(激活的)视图负责记录) ,只负责即时绘画就可以。如果是windows///

/的那么此兄弟视图目前成为了当前(激活的视图)。                                                                                                        

 

不过这样的设计会牵扯到如下两个问题:

1:如何区分windows消息和兄弟视图发送的消息?

2:如何实现数据的单一副本,而不会存在每个子视图一份数据(因为笔画的数据创建,添加是在OnLButtonDown,OnLButtonUp,

OnMouseMove里完成),所以不能照搬单视图的方法。

 

解决方式:

1:其他视图通过nFlags标记位判断此消息是兄弟视图发送的消息,还是windows发送的消息以区别对待。     

2:由鼠标激活的视图完成笔画数据创建,以及添加工作。其他视图是负责绘画。

 

解决完上面两方面就可以完成多视图同步高效率绘画问题。下面是我所设计的数据和函数:

//Doc.h

//Doc.cpp/

 

//view.h///

//view.cpp

//CStroke.h//

//CStroke.cpp

 

在滚动窗口中使显示时,为了使激活视图(被鼠标激活的)和兄弟视图在逻辑上同步,必须让激活视图完成两个任务。

1:进行设备坐标绘画。

2:逻辑坐标添加点信息

注意设备坐标只是在绘图上使用,而文件保存的是逻辑坐标。

 

兄弟视图要完成的任务只有,完成逻辑坐标绘画。这就和激活视图有着既然相反的绘画方式。

滚动窗口的响应代码:

//Doc.h

//Doc.cpp

//view.h

//view.cpp

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值