您的位置:首页 > 其它

关于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)如何查看消息队列?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: