先看一段代码:
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)如何查看消息队列?