`

OnEraseBkgnd与onpaint的联系(转载)

 
阅读更多

题是这样产生的.在OnEraseBkGnd中,如果你不调用原来缺省
的OnEraseBkGnd只是重画背景则不会有闪烁.而在OnPaint里面,
由于它隐含的调用了OnEraseBkGnd,而你又没有处理OnEraseBkGnd
函数,这时就和窗口缺省的背景刷相关了.缺省的
OnEraseBkGnd操作使用窗口的缺省背景刷刷新背景(一般情况
下是白刷),而随后你又自己重画背景造成屏幕闪动.
另外一个问题是OnEraseBkGnd不是每次都会被调用的.如果你
调用Invalidate的时候参数为TRUE,那么在OnPaint里面隐含
调用BeginPaint的时候就产生WM_ERASEBKGND消息,如果参数
是FALSE,则不会重刷背景.

所以解决方法有三个半:
1.用OnEraseBkGnd实现,不要调用原来的OnEraseBkGnd函数.
2.用OnPaint实现,同时重载OnEraseBkGnd,其中直接返回.
3.用OnPaint实现,创建窗口时设置背景刷为空
4.用OnPaint实现,但是要求刷新时用Invalidate(FALSE)这样
的函数.(不过这种情况下,窗口覆盖等造成的刷新还是要闪一
下,所以不是彻底的解决方法)
都挺简单的.
------------------------------------------------------
在MFC中 任何一个window组件的绘图 都是放在这两个member function中
在设定上 OnEraseBkgnd()是用来画底图的 而OnPaint()是用来画主要对象的
举例说明 一个按钮是灰色的 上面还有文字
则OnEraseBkgnd()所做的事就是把按钮画成灰色
而OnPaint()所做的事 就是画上文字

既然这两个member function都是用来画出组件的
那为何还要分OnPaint() 与 OnEraseBkgnd() 呢
其实OnPaint() 与 OnEraseBkgnd() 特性是有差的
1. OnEraseBkgnd()的要求是快速 在里面的绘图程序最好是不要太耗时间
因为 每当window组件有任何小变动 都会马上呼叫OnEraseBkgnd()
2. OnPaint() 是只有在程序有空闲的时候才会被呼叫
3. OnEraseBkgnd() 是在 OnPaint() 之前呼叫的
所以 OnPaint()被呼叫一次之前 可能会呼叫OnEraseBkgnd()好几次


如果我们是一个在做图形化使用者接口的人
常会需要把一张美美的图片设为我们dialog的底图
把绘图的程序代码放在OnPaint() 之中 可能会常碰到一些问题
比方说拖曳一个窗口在我们做的dialog上面一直移动
则dialog会变成灰色 直到动作停止才恢复
这是因为每次需要重绘的时候 程序都会马上呼叫OnEraseBkgnd()
OnEraseBkgnd()就把dialog画成灰色
而只有动作停止之后 程序才会呼叫OnPaint() 这时才会把我们要画的底图贴上去


这个问题的解法 比较差点的方法是把OnEraseBkgnd() 改写成不做事的function
如下所示
BOOL CMyDlg::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
以上本来是会呼叫CDialog::OnEraseBkgnd() 但是如果我们不呼叫的话
程序便不会画上灰色的底色了


比较好的做法是直接将绘图的程序从OnPaint()移到OnEraseBkgnd()来做
如下所示

// m_bmpBKGND 为一CBitmap对象 且事先早已加载我们的底图
// 底图的大小与我们的窗口client大小一致


BOOL CMyDlg::OnEraseBkgnd(CDC* pDC)
{
CRect rc;
GetUpdateRect(&rc);
CDC srcDC;
srcDC.CreateCompatibleDC(pDC);
srcDC.SelectObject(m_bmpBKGND);

pDC->BitBlt(rc.left,rc.top,rc.GetWidth(),
rc.GetHeight(),&srcDC,rc.left,rc.top,SRCCOPY);
return TRUE;
}

特别要注意的是 取得重画大小是使用GetUpdateRect() 而不是GetClientRect()
如果使用GetClientRect() 会把不该重画的地方重画

分享到:
评论

相关推荐

    【转】绘制_OnPaint和OnEraseBkgnd的联系

    在VC++中常用的OnPaint和OnEraseBkgnd,在这篇简短的文档中,粗略的讲解了一下两者的 联系,旨在给大家一点启发与提示、

    OnPaint()的工作原理

    MFC中改变对话框背景的几个消息函数的调用顺序、VC中OnPaint()的工作原理.

    用实验理解 Invalidate,InvalidateRect,OnEraseBkgnd(CDC* pDC),OnPaint() 之间的关系

    用实验理解 Invalidate,InvalidateRect,OnEraseBkgnd(CDC* pDC),OnPaint() 之间的关系,调试的时候先点击开始,然后注意看窗口的标题栏 等过了一段时间后,分别点击其他三个按钮,最好用vs2003调试 vs2013也行

    易语言窗口复制模块

    窗口复制模块,取复制窗口标记,复制整个窗口,复制控件,处理随意移动,CopyWindow_OnMessage,CopyWindow_CallSrcWindowProc,CopyWindow_OnDestroy,CopyWindow_OnLButtonDown,CopyWindow_OnEraseBkgnd,CopyWindow_...

    单文档实现图片移动

    MFC创建一个单文档,实现图片在客户区来回移动

    mfc鼠标点击绘图并保存图像

    在mfc窗口中绘图画线,刷新后也不会消失,保存图像文件到本地,限定鼠标样式及移动范围,实时提示坐标位置,修改窗口背景色,没有标题栏也能通过鼠标按住移动窗口;代码精练,功能齐全,注释详细

    VC++做异形窗口 透明效果

    标准Windows应用程序窗口一般为带有标题栏的浅灰色矩形外观,因而“异形”对话框/窗口也主要是颜色与外形上动手脚。改变背景颜色 改变对话框(窗口)的背景颜色是最简单的改变Windows应用程序外观的方法,根据...

    VC之美化界面篇本文专题讨论VC中的界面美化,适用于具有中等VC水平的读者。读者最好具有以下VC基础:

    表2 nCtlColor的类型值与含义 作为一个简单的例子,观察以下的代码: BOOL CUi5Dlg::OnInitDialog() { //… //创建字体 //CFont CUi1View::m_Font1, CUi1View::m_Font2 m_Font1.CreatePointFont(120, "Impact...

    clock_ctrl_src,clock_src

    afx_msg BOOL OnEraseBkgnd(CDC* pDC); //}}AFX_MSG void RecalcLayout(); double MinuteToRadian(double minute); CPoint ComputePoint(int nMinute, double ratio); void DrawFacePoint(CDC& dc, const ...

    MFC双缓存无闪烁画图

    OnEraseBkgnd(CDC* pDC)方法里实现了无闪烁切换背景图。。。

    网络右下角弹出新闻窗口_VC源码.rar

    LRESULT OnEraseBkgnd(UINT message, WPARAM wParam, LPARAM lParam); LRESULT OnPaint(UINT message, WPARAM wParam, LPARAM lParam); LRESULT OnMouseMove(UINT message, WPARAM wParam, LPARAM lParam); ...

    双缓冲绘图实现图片查看格式转换器

    基于MFC单文档的图片查看格式转换器 功能描述: 1、支持BMP,JPG,GIF,PNG等多种格式相互转换(打开->另存为) ...PS:双缓冲绘图为两步:一是创建内存DC,二是重写OnEraseBkgnd(CDC* pDC)函数。

    MFCAppTest-自绘动画窗口.rar

    VS2017代码,MFC自绘制窗口:以动态形式实现自绘制窗口的淡入和淡出,主要知识点包括:SetTimer、OnEraseBkgnd、MoveWindow、KillTimer等函数的应用

    CEdit_Fainal

    BOOL CMyEdit::OnEraseBkgnd(CDC* pDC) { CDC memDC; memDC.CreateCompatibleDC(pDC); memDC.SelectObject(&m_Bitmap); BITMAP m_Bmp; m_Bitmap.GetBitmap(&m_Bmp);

    如何在MFC程序中调用OpenGL

    讲述了如何在MFC单文档程序中应用OpenGL进行显示 后面用的过程中发现调整窗口大小时背景会闪烁,需要添加WM_ERASEBKGND消息,并注释掉CView::OnEraseBkgnd(),直接 return TRUE;

    DrawBackground用VC++实现,改变窗口背景

    对多文档窗口应用程序中的主框架,可改变窗口的背景,使程序看起来更专业,窗口改变背景不能简单地用ClassWizard重载OnEraseBkgnd(CDC* pDC)函数的方法 实现。 因为多文档窗口应用程序中的主框架窗口的背景区是一个...

    基于MFC单文档的OpenGL环境配置

    基于MFC单文档的OpenGL环境配置 基于MFC单文档的OpenGL环境配置 基于MFC单文档的OpenGL环境配置 //return CView::OnEraseBkgnd(pDC); //注释掉,消除绘图屏幕闪烁问题,改为 return TRUE;

    ATL窗口实现

    MESSAGE_HANDLER(WM_ERASEBKGND,CPaintBkgndBase::OnEraseBkgnd) 这样更能体现ATL类的扩展特征。 3.ATL比起MFC的稍微不便的地方是需要手动添加消息处理宏,以及 消息处理函数中需要分清WPARAM wParam和LPARAM ...

    在vc6.0中 画实时曲线

    1.重载了OnEraseBkgnd函数,它是用来在每次重绘之前用空白位图擦除背景的函数,我们让它每次用我们自定义的位图来作为背景 2.我们使用了双缓存的结构,即先把背景图形绘制在内存中,绘制好了一起显示出去

    VC—主框架窗口绘制背景

    使 用VC进行项目开发,特别是简单的MIS系统开发中,通常在用户没有进行操作之前显示的是主框架的窗口(用户点击...但是对于主框架的背景的绘制不能简单地用ClassWizard重载 OnEraseBkgnd(CDC* pDC)函数的方法实现。

Global site tag (gtag.js) - Google Analytics