zoukankan      html  css  js  c++  java
  • 关于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() 会把不该重画的地方重画.

  • 相关阅读:
    Android开源demo---芒果TV-VIP电影播放器
    实现sqrt()函数
    std::string内容包含双引号
    解决win10 SVN不显示绿色和红色的状态显示标志
    win 10 解决 caps键无法退出大写的问题
    webrtc 编译问题:running depot tools as root is sad 的解决办法
    Linux下运行脚本显示“: /usr/bin/env: "bash ": 没有那个文件或目录
    解决报错:no acceptable C compiler found in $PATH when installing python
    linux 打开文件管理器
    windows打开U盘提示 文件或目录损坏且无法读取 解决办法
  • 原文地址:https://www.cnblogs.com/RascallySnake/p/3395556.html
Copyright © 2011-2022 走看看