OnPaint()与OnEraseBkgnd()

在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() 会把不该重画的地方重画

 

BOOL CbackdropDlg::OnEraseBkgnd(CDC* pDC)
{
     CDC memDC;
    CBitmap bitmap;
   
    memDC.CreateCompatibleDC(pDC);
//    bitmap.LoadBitmap(IDB_BITMAP1);
switch(bkbmp_n)
{
case 0:bitmap.LoadBitmap(IDB_BACKGROUND);
 break;
case 1:bitmap.LoadBitmap(IDB_BITMAP1);
 break;
case 2:bitmap.LoadBitmap(IDB_BITMAP2);
 break;
default:bitmap.LoadBitmap(IDB_BACKGROUND);
}

    memDC.SelectObject(&bitmap);

    RECT rt;
    GetClientRect(&rt);
    pDC->StretchBlt(0,0,rt.right-rt.left,rt.bottom-rt.top,&memDC,0,0,427,317,SRCCOPY);
    return TRUE; 
 
 return CDialog::OnEraseBkgnd(pDC);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值