文章类型: VC&C++
关键词: VC++,ondraw,何时,在什么时候,调用
内容摘要: VC++中ondraw在什么时候调用的

VC++中ondraw在什么时候调用的

2018/2/6 10:56:06    来源:apple    阅读:

问题:我在视图画的图象或者文字,当窗口改变后为什么不见了?OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同?

因为当你的窗口改变后,会产生无效区域,这个无效的区域需要重画。一般Windows回发送两个消息WM_PAINT(通知客户区有变化)和 WM_NCPAINT(通知非客户区有变化)。非客户区的重画系统自己搞定了,而客户区的重画需要我们自己来完成。这就需要OnDraw()或 OnPaint()来重画窗口。

OnDraw()和OnPaint()有什么区别呢?

首先:我们先要明确CView类派生自CWnd类。而OnPaint()是CWnd的类成员,同时负 责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数,并且没有响应消息的功能。这就是为什么你用VC的程序代码时,在视图类只有 OnDraw没有OnPaint的原因。

其次:要想在屏幕上绘图或显示图形,首先需要建立设备环境DC,其实DC(Device Context设备上下文)是一个结构,它定义了一系列图形对象及其相关的属性,也就是设备环境的属性的集合,这些设备包括打印设备。显示设备,输出设备等,这些图形对象包括:画笔(用于画直线),笔刷(用于绘图和填充),位图(用于屏幕的拷贝或滚动),调色板(用于定义可用的颜色集),剪裁区(用于剪裁和其他操作),路径(用于绘图和画图操作)。


MFC提供了CPaintDC类和CWindwoDC类来实时的响应,而CPaintDC支持重画。

当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows 将 WM_PAINT 消息发送给它。该视图的 OnPaint 处理函数通过 创建 CPaintDC 类的DC对象来响应该消息并调用视图的 OnDraw 成员函数。通常我们不必编写重写的 OnPaint 处理成员函数。

///CView默认的标准的重画函数
void CView::OnPaint()
{
    CPaintDC dc(this); 
    OnPreparDC(&dc);
    OnDraw(&dc); //调用了OnDraw
}

既然OnPaint最后也要调用OnDraw,因此我们一般会在OnDraw函数中进行绘制。下面是一个典型的程序

///视图中的绘图代码首先检索指向文档的指针,然后通过DC进行绘图调用。

void CMyView::OnDraw( CDC* pDC ) 
{ 
    CMyDoc* pDoc = GetDocument(); 
    CString s = pDoc->GetData(); // Returns a CString CRect rect;
    GetClientRect( &rect ); 
    pDC->SetTextAlign( TA_BASELINE | TA_CENTER );
    pDC->TextOut( rect.right / 2, rect.bottom / 2, s, s.GetLength() );
}

因此我们一般用OnPaint维护窗口的客户区(例如我们的窗口客户区加一个背景图片),用OnDraw维护视图的客户区(例如我们通过鼠标在视图中画图)。当然你也可以不按照上面规律来,只要达到目的并且没有问题,怎么干都成。

补充:我们还可以利用Invalidate(),ValidateRgn(),ValidateRect()函数强制的重画窗口,具体的请参考MSDN


↑ 上一篇文章:土豪与政治腐败——马尔克斯的《大妈的葬礼》 关键词:加西亚,马尔克斯,哥伦比亚,土豪,政治腐败,大妈的葬礼,.. 发布日期:2018/1/18 11:34:30
↓ 下一篇文章:权限,角色,分组,部门 关键词:权限,角色,分组,部门,E-R图,权限管理,实体关系图E.. 发布日期:2018/2/27 9:53:42
相关文章:
vc++之调用CloseHandle的原因 关键词:vc++之调用CloseHandle的原因 发布日期:2017-01-10 14:49
VC++调用ADO运行带参数的存储过程 关键词:VC++调用ADO运行带参数的存储过程 发布日期:2016-09-22 09:27
VC++中delete与delete[]的区别 关键词:VC++,delete,区别 发布日期:2016-12-05 16:16
相关目录:.NETVC&C++软件开发
我要评论
正在加载评论信息......