woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

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() 會把不該重畫的地方重畫

 

posted on 2010-07-10 13:44 肥仔 阅读(707) 评论(0)  编辑 收藏 引用 所属分类: MFC存档


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理