VC图形重绘(闪烁)问题
想实现windows自带的画图程序的部分功能,如画直线时,按下左键后直线会随鼠标移动而跟踪画线(网上代码一般是按下左键,再放开左键才出现一条直线),我有试过用CPtrAr...
想实现windows自带的画图程序的部分功能,如画直线时,按下左键后直线
会随鼠标移动而跟踪画线(网上代码一般是按下左键,再放开左键才出现一条直线),我有试过用CPtrArray来存储关键信息,再在OnDraw中重绘保存的对象,但每响应一次MouseMove都得调用一次OnDraw,效率很低,所以会明显的看到闪烁,希望哪位高人指点。
还有当画线时,鼠标(快速)移出窗口会明显感到由于OnMouseMove延迟导致画出的线条不行到达边界;windows自带的画图程序好像鼠标移出窗口外也能在客户区有所反应,请教下它实现原理。 展开
会随鼠标移动而跟踪画线(网上代码一般是按下左键,再放开左键才出现一条直线),我有试过用CPtrArray来存储关键信息,再在OnDraw中重绘保存的对象,但每响应一次MouseMove都得调用一次OnDraw,效率很低,所以会明显的看到闪烁,希望哪位高人指点。
还有当画线时,鼠标(快速)移出窗口会明显感到由于OnMouseMove延迟导致画出的线条不行到达边界;windows自带的画图程序好像鼠标移出窗口外也能在客户区有所反应,请教下它实现原理。 展开
3个回答
展开全部
1.画直线问题
实现鼠标移动中画线的思路是这样的
按下鼠标后,保存住按下时的鼠标位置,并设置一标记指明现在鼠标按下了
鼠标移动事件中,如果有鼠标按下的标记,就先重绘界面,然后在画一条线
鼠标释放的时候再画一条线
2.效率问题
频繁调用OnDraw并不是效率低的原因
一个函数被频繁调用也不是效率低的体现
3.闪烁问题
这是一个经典问题
界面刷新的时候先要清空一次然后绘制
过程频繁的话必然引起闪烁
解决的办法是双缓冲
关键是取消背景擦除
就是响应WM_ONERASEBKGND消息然后什么也不做
构建一个后台的内存位图
每次作图的时候在这个位图上作
然后在OnDraw中将这个位图复制到界面上来
整幅图的复制是非常快的
这样的话就消除了闪烁
注:这里界面上的背景擦除去掉了
内存中的还是需要的
每次画线要先清空内存位图
涉及到你做的具体程序
你可能需要保持住之前已经画好的图形
这样你还需要一个内存位图协调工作
仔细想想
4.边界问题
鼠标出了边界
一般情况下鼠标的移动消息也就得不到了
Windows提供了专门的函数解决这个问题
即在鼠标按下的同时捕获鼠标(SetCapture)
这样鼠标出了边界,捕获鼠标的窗口也能收到鼠标移动消息
在鼠标弹起的时候注意释放捕获的鼠标(ReleaseCapture)
5.双缓冲的资料
我学习这个时候的笔记,看看吧
http://hi.baidu.com/shilyx/blog/item/3662711e18ec7bf41ad576fc.html
http://hi.baidu.com/shilyx/blog/item/469f8b9462670a1ed31b7022.html
实现鼠标移动中画线的思路是这样的
按下鼠标后,保存住按下时的鼠标位置,并设置一标记指明现在鼠标按下了
鼠标移动事件中,如果有鼠标按下的标记,就先重绘界面,然后在画一条线
鼠标释放的时候再画一条线
2.效率问题
频繁调用OnDraw并不是效率低的原因
一个函数被频繁调用也不是效率低的体现
3.闪烁问题
这是一个经典问题
界面刷新的时候先要清空一次然后绘制
过程频繁的话必然引起闪烁
解决的办法是双缓冲
关键是取消背景擦除
就是响应WM_ONERASEBKGND消息然后什么也不做
构建一个后台的内存位图
每次作图的时候在这个位图上作
然后在OnDraw中将这个位图复制到界面上来
整幅图的复制是非常快的
这样的话就消除了闪烁
注:这里界面上的背景擦除去掉了
内存中的还是需要的
每次画线要先清空内存位图
涉及到你做的具体程序
你可能需要保持住之前已经画好的图形
这样你还需要一个内存位图协调工作
仔细想想
4.边界问题
鼠标出了边界
一般情况下鼠标的移动消息也就得不到了
Windows提供了专门的函数解决这个问题
即在鼠标按下的同时捕获鼠标(SetCapture)
这样鼠标出了边界,捕获鼠标的窗口也能收到鼠标移动消息
在鼠标弹起的时候注意释放捕获的鼠标(ReleaseCapture)
5.双缓冲的资料
我学习这个时候的笔记,看看吧
http://hi.baidu.com/shilyx/blog/item/3662711e18ec7bf41ad576fc.html
http://hi.baidu.com/shilyx/blog/item/469f8b9462670a1ed31b7022.html
展开全部
你的画法应该还是可以的,可以使用双缓冲绘图避免闪烁,网上很容易找到的.
至于你说的"鼠标移出窗口外也能在客户区有所反应",你只需要在鼠标按下的时候SetCapture,在鼠标放开的时候ReleaseCapture就可以了.
具体原理你可以看看windows编程方面的书,基本上都有.
至于你说的"鼠标移出窗口外也能在客户区有所反应",你只需要在鼠标按下的时候SetCapture,在鼠标放开的时候ReleaseCapture就可以了.
具体原理你可以看看windows编程方面的书,基本上都有.
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
别在OnDraw里实现。
增加消息响应OnLButtonDown ,OnLButtonUp ,OnMouseMove实现
在OnLButtonDown响应中将1个BOOL变量设置为真,在OnMouseMove中判断BOOL值画图。在OnLButtonUp响应中将该BOOL变量设置为假。
补充:
我觉得闪烁是因为每次重绘会时,会先擦除背景。擦除频繁会出现闪烁。
或许能解决的办法是把需要绘制的代码段放到OnEraseBkgnd消息响应中处理,注意把返回值改成TRUE才能避免调用默认的处理。把生成的注释掉。
return TRUE;
// return CView::OnEraseBkgnd(pDC);
3楼所说的"响应WM_ONERASEBKGND消息然后什么也不做"我觉得不改成TRUE,等于白写。
注:我是初学者~刚学到解决位图重绘闪烁的问题,我这样可以解决我的问题。不知道能不能解决你的问题~说错的地方多多包涵~
增加消息响应OnLButtonDown ,OnLButtonUp ,OnMouseMove实现
在OnLButtonDown响应中将1个BOOL变量设置为真,在OnMouseMove中判断BOOL值画图。在OnLButtonUp响应中将该BOOL变量设置为假。
补充:
我觉得闪烁是因为每次重绘会时,会先擦除背景。擦除频繁会出现闪烁。
或许能解决的办法是把需要绘制的代码段放到OnEraseBkgnd消息响应中处理,注意把返回值改成TRUE才能避免调用默认的处理。把生成的注释掉。
return TRUE;
// return CView::OnEraseBkgnd(pDC);
3楼所说的"响应WM_ONERASEBKGND消息然后什么也不做"我觉得不改成TRUE,等于白写。
注:我是初学者~刚学到解决位图重绘闪烁的问题,我这样可以解决我的问题。不知道能不能解决你的问题~说错的地方多多包涵~
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询