mfc闪烁显示文字,mfc弹出窗口

  mfc闪烁显示文字,mfc弹出窗口

  双缓冲是图形图像处理编程过程中的一项基本技术。我们知道,如果窗体在响应WM_PAINT消息时需要复杂的图形处理,那么窗体在重绘时会因为超频刷新而闪烁。解决这一问题的有效方法是双缓冲技术。

  因为表单刷新的时候,总有一个擦除原图的过程。OnEraseBkgnd用背景色填充窗体的绘制区域,然后调用新的绘制代码进行重绘,这样就造成了图像颜色的对比。当WM_PAINT的响应频繁时,这种反差就越来越明显。所以我们看到了闪烁现象。

  我们自然会认为避免背景色填充是最直接的方式。但那样的话,形式就会变得一塌糊涂。因为每次绘制图像的时候都没有清除原图,造成了图像的残留,所以在重绘表单的时候,画面往往会变得凌乱。所以仅仅禁止背景重绘是不够的。我们要重画,但是需要快,所以想到了用BitBlt函数。可以支持图形块的复制,速度非常快。我们可以先在内存中画一个图,然后用这个函数把完成的图复制到前台。同时禁止背景刷新,从而消除闪烁。这就是双缓冲绘图的基本思想。

  首先,按照常用的画图方法编程。即在visual类的OnDraw函数中添加绘图代码。这里我们用下面的代码画一些同心圆:【cpp】查看plaincopyprint?

  CBCDoc * pDoc=get document();ASSERT _ VALID(pDoc);CPointptCenterCRectrect,ellipseRectGetClientRect(rect);ptCenter=rect。中心点();for(inti=20;我i - ){ellipseRect。SetRect(ptCenter,pt center);ellipseRect。InflateRect直立(i*10,I * 10);pDC椭圆(ellipseRect);} CBCDoc * pDoc=get document();

  ASSERT _ VALID(pDoc);

  CPoint ptCenter

  CRect rect,ellipseRect

  GetClientRect(rect);

  ptCenter=rect。中心点();

  for(int I=20;我我-)

  ellipseRect。SetRect(ptCenter,pt center);

  ellipseRect。InflateRect直立(i*10,I * 10);

  pDC椭圆(ellipseRect);

  运行程序,尝试改变窗口大小,可以发现闪烁现象。

  在双缓冲法中,首先要做的是屏蔽背景刷新。后台刷新实际上是响应WM_ERASEBKGND消息。我们在可视类中添加对该消息的响应,我们可以看到缺少的

  各省代码如下:

  【cpp】查看plaincopyprint?

  BOOLCMYView:OnEraseBkgnd(CDC * pDC){ return cview:OnEraseBkgnd(pDC);} BOOL cmy view:OnEraseBkgnd(CDC * pDC)

  返回CView:OnEraseBkgnd(pDC);

  }

  调用父类的是OnEraseBkgnd函数。我们屏蔽这个调用,直接返回TRUE去做吧。

  下面是内存缓冲区映射的步骤。

  【cpp】查看plaincopyprint?

  CBitmapbit有点。LoadBitmapA(IDB _ bitmap 1);BITMAPbm有点。get bitmap(BM);CDCmemDcmemDc。CreateCompatibleDC(pDC);CBitmap*pOldBitmap=memDc。SelectObject(位);CRectrectGetClientRect(rect);pDC-SetStretchBltMode(COLORONCOLOR);//如果不设置这种模式,画面会严重失真PDC-StretchBLT (0,0,rect.width(),rect.height(),memdc,0,0,bm.bmwidth,bm.bmheight,src copy);memDc。select object(pOldBitmap);memDc。DeleteDC();//删除DC兽王。delete object();//删除位图CBitmap位;

  有点。LoadBitmapA(IDB _ bitmap 1);

  位图BM;

  有点。get bitmap(BM);

  CDC memDc

  memDc。CreateCompatibleDC(pDC);

  CBitmap* pOldBitmap=memDc。SelectObject(位);

  CRect rect

  GetClientRect(rect);

  pDC-SetStretchBltMode(COLORONCOLOR);//如果不设置这个模式,画面会严重失真。

  pDC- StretchBlt(0,0,rect。Width(),rect。身高(),

  memDc,0,0,bm.bmWidth,bm.bmHeight,src copy);

  memDc。select object(pOldBitmap);

  memDc。DeleteDC();//删除DC

  bm。delete object();//删除位图

  随着复杂的绘图操作进入后台,我们看到的是快速的复制操作,自然消除了闪烁现象。

  问:onerasebkgnd函数中返回TRUE或FALSE有什么区别?

  答:

  WM_ERASEBKGND

  返回值

  如果应用程序删除了背景,它应该返回非零值;否则,它应该返回零。

  答:true表示后台刷新已处理,false表示需要在OnPaint中处理。

  问:在OnEraseBkgnd中绘制对话框背景图和在OnPaint中绘制对话框背景图有什么区别?OnEraseBkgnd和CtlColor有什么区别?

  答:

  OnEraseBkgnd发生在窗口大小改变等情况下。它将绘制窗口背景;而OnCtlColor发生在需要绘制窗口的控件时,它会绘制窗口的

  控制。

  答:

  OnEraseBkgnd:当需要重画窗口背景时调用。

  OnPaint: OnEraseBkgnd此时已经被调用,所以这个响应函数中对后台的操作会覆盖OnEraseBkgnd中的操作。

  OncColor:为了在将要绘制窗口时(第一次)做出响应,子窗口可以通过关闭WM_CTLCOLOR来请求父窗口发送HBRUSH。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: