关于MFC中InvalidateRect()的思考与疑问
2015-09-23 16:20
351 查看
先看一段代码:
void CFeatureEdit_LinePolyDLG::DrawRectAll(int type)
{
CClientDC dc(this);
//底框画笔
CPen penRect(PS_DOT,1,RGB(0,125,0));
CPen *oldPenRect = (CPen*)dc.SelectObject(&penRect);
CBrush brRect(RGB(255,255,255));
CBrush *oldbrRect = (CBrush*)dc.SelectObject(&brRect);
//
InvalidateRect(&m_RectShowFillImage);//设置无效区
//Draw something in m_RectShowFillImage……
//
InvalidateRect(&m_RectShowLineType);//设置无效区
//Draw something in m_RectShowLineType……
//
dc.SelectObject(&oldPenRect);
penRect.DeleteObject();
dc.SelectObject(&oldbrRect);
brRect.DeleteObject();
}
这段代码用来绘制几个区域图案,对话框并没有重载OnPaint()函数,也没调用Invalidate()设置整个客户区为无效区,打算手动发送WM_PAINT消息开进行刷新。
一开始使用InvalidateRect()进行无效区域设置,但是绘制的图案并没有显示。
查阅资料,发现InvalidateRect()设置无效区后,会发送一条WM_PAINT消息到消息队列。但是由于WM_PAINT的优先级很低,因此并不能及时的进行处理。
怀疑是此处问题,资料中发现,UpdateWindow()可以绕过消息队列,直接向窗体提交WM_PAINT消息,并且其无效区域将自己调用GetUpdateRect获得,即为上一条WM_PAINT设置的无效区域,然后窗体会立即处理此消息;
因此在InvalidateRect()调用之后直接调用UpdateWindow(),代码部分修改如下:
InvalidateRect(&m_RectShowFillImage);//设置无效区
UpdateWindow();
//Draw something in m_RectShowFillImage……
InvalidateRect(&m_RectShowLineType);//设置无效区
UpdateWindow();
//Draw something in m_RectShowLineType……
果然可以实现预定功能。
但是就此处存在几个疑问疑问如下:
(1)既然InvalidateRect也发送了重绘消息,在未加UpdateWindow之前调试也能看到绘制成功,为何跳出该函数(DrawRectAll)时图案还存在,但是继续运行之后就消失了?
(2)理论上加不加UpdateWindow只会出现绘制先后的差别,为何在此段代码中重新绘制图案后会被覆盖掉?
(3)如何查看消息队列?
void CFeatureEdit_LinePolyDLG::DrawRectAll(int type)
{
CClientDC dc(this);
//底框画笔
CPen penRect(PS_DOT,1,RGB(0,125,0));
CPen *oldPenRect = (CPen*)dc.SelectObject(&penRect);
CBrush brRect(RGB(255,255,255));
CBrush *oldbrRect = (CBrush*)dc.SelectObject(&brRect);
//
InvalidateRect(&m_RectShowFillImage);//设置无效区
//Draw something in m_RectShowFillImage……
//
InvalidateRect(&m_RectShowLineType);//设置无效区
//Draw something in m_RectShowLineType……
//
dc.SelectObject(&oldPenRect);
penRect.DeleteObject();
dc.SelectObject(&oldbrRect);
brRect.DeleteObject();
}
这段代码用来绘制几个区域图案,对话框并没有重载OnPaint()函数,也没调用Invalidate()设置整个客户区为无效区,打算手动发送WM_PAINT消息开进行刷新。
一开始使用InvalidateRect()进行无效区域设置,但是绘制的图案并没有显示。
查阅资料,发现InvalidateRect()设置无效区后,会发送一条WM_PAINT消息到消息队列。但是由于WM_PAINT的优先级很低,因此并不能及时的进行处理。
怀疑是此处问题,资料中发现,UpdateWindow()可以绕过消息队列,直接向窗体提交WM_PAINT消息,并且其无效区域将自己调用GetUpdateRect获得,即为上一条WM_PAINT设置的无效区域,然后窗体会立即处理此消息;
因此在InvalidateRect()调用之后直接调用UpdateWindow(),代码部分修改如下:
InvalidateRect(&m_RectShowFillImage);//设置无效区
UpdateWindow();
//Draw something in m_RectShowFillImage……
InvalidateRect(&m_RectShowLineType);//设置无效区
UpdateWindow();
//Draw something in m_RectShowLineType……
果然可以实现预定功能。
但是就此处存在几个疑问疑问如下:
(1)既然InvalidateRect也发送了重绘消息,在未加UpdateWindow之前调试也能看到绘制成功,为何跳出该函数(DrawRectAll)时图案还存在,但是继续运行之后就消失了?
(2)理论上加不加UpdateWindow只会出现绘制先后的差别,为何在此段代码中重新绘制图案后会被覆盖掉?
(3)如何查看消息队列?
相关文章推荐
- iOS里面KVO模式的详解和使用
- List和ArrayList, Map和HashMap的区别
- UIScrollView && UIPageControl
- MySQL的随机数函数rand()的使用技巧
- PAT(甲级)1008
- Spring中注解的使用
- apue.h头文件的配置
- Android 应用程序之间内容分享详解(一)
- iOS开发——枚举类型和闭包
- 如果你还在用STM32F103,那么你OUT了
- 架构设计的常用思想
- Retrofit学习笔记(一)
- solr 如何实现精确查询
- Android软键盘弹出将底部栏顶上去并不会挤压界面
- 华为机试测试- 求有序数组中最长的等差序列
- Unity3D之Mecanim动画系统学习笔记(七):IK(反向动力学)动画
- 解决arm92410下载程序进去出现
- NSMutableArray替换对象
- Spring中关于bean的继承
- C++序列化方法 参考google protobuf