关于MFC中InvalidateRect()的思考与疑问

先看一段代码:

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)如何查看消息队列?

上一篇:Gson如何解析key值是数字的json数据


下一篇:修改hosts文件(判断是否为管理员/以管理员权限运行脚本)