我在文档工作区画一条线,更改其线条颜色调用下面的函数
void CSketcherView::OnElementChangecolor()
{
CColorDialog ColorDialog;
if (ColorDialog.DoModal() == IDOK)
{
m_ChangeColor = ColorDialog.GetColor();
m_pSelected->m_Color = m_ChangeColor;//改变当前选择元素的颜色
}
GetDocument()->UpdateAllViews(nullptr,0,m_pSelected.get());//本意调用OnDraw函数重新绘制所有元素,但是貌似没用
}
问题如后面的最后一行的注释。本意在想着调用此函数后会调用OnDraw函数,OnDraw函数完成对工作区中包含的各个线条重新绘制功能,进而改变了颜色。然而实际并不能马上使这根线条变色。
解决方法:
将GetDocument()->UpdateAllViews(nullptr,0,m_pSelected.get());//注释掉,换成下面的两行代码即可。想想也是,在View类中调用GetDocument指针的UpdateAllViews函数,势必有些影响。
CClientDC aDc(this);
m_pSelected->Draw(&aDc);
void Invalidate( BOOL bErase = TRUE ); 该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,参数bErase为TRUE时,重绘区域内的背景将被重绘即擦除,否则,背景将保持不变。调用Invalidate等函数后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理。
解决方案:
OnDraw,一般是收到WM_PAINT消息时调用,所以应用程序一般通过Invalidate产生WM_PAINT消息来间接调用OnDraw。当窗体无效等情况下,window也会产生WM_PAINT消息,这时OnDraw 也被间接调用。
OnUpdate 是CView提供的一个方法,一般当文档修改时调用,应用程序框架在CView::OnInitialUpdate 和CDocument::UpdateAllViews 的默认实现中都会调用
OnUpdate,OnUpdate的默认实现是通过Invalidate产生WM_PAINT,这时OnDraw又被调用了。
个人总结:发送的WM_PAINT 消息并不会立刻得到相应,因为其优先级比较低,只有其他消息响应完毕才响应