用MFC对话框做无闪烁图片重绘

原创 2004年03月29日 10:26:00

用应用程序向导生成一个基于对话框的应用程序

把对话框Styles里的Border设置为Resizing,并把Minimize box跟Maximize box复选按钮都勾上

现在我们为资源导入一张位图然后我们为程序添加四个私有变量private:
 int height;
 int width;
 CBitmap myBitmap;
 BITMAP bm;

然后用类向导添加WM SIZE消息输入下列代码: width = cx;
 height = cy;
 Invalidate();

然后在添加WM_PAINT消息在函数里添加以下代码: CDC *pDC=new CDC;
 CPaintDC dc(this);
 //CClientDC dc(NULL);
 pDC->CreateCompatibleDC(&dc);
 pDC->SelectObject(myBitmap);
 //将图片伸缩成我们设定的大小。
 dc.StretchBlt(0,0,width,height,pDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
 //如果不准备进行缩放可以用BITBLT。 
 //dc.BitBlt(0,0,bm.bmWidth,bm.bmHeight,pDC,0,0,SRCCOPY);

 delete pDC;

然后做最后一步在程序初始化时候导入我们的图片并让对话大小跟图片一样

在 OnInitDialog函数最里添加如下代码:

// TODO: Add extra initialization here
 myBitmap.LoadBitmap(IDB_BITMAP1);
 myBitmap.GetObject(sizeof(BITMAP),&bm);

好了我们现在就做了一个可以显示图片的对话框并且对话改变大小的时候图片大小也会改变,不过这个程序有一个缺点,就是重绘的时候有闪烁,性能不怎么好,

现在我们按上面的步骤在做一个对话框,导入位图,

添加以下变量:public:
 CSize    m_sizeBuffer;
 CBitmap  m_bmpBackBuffer;
 CBitmap* m_pbmpPattern;

在OnInitDialog函数里添加以下代码

m_pbmpPattern=CBitmap::FromHandle((HBITMAP)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_BACKGROUND), IMAGE_BITMAP, 0,0, LR_SHARED));

重写OnPaint函数

if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // Draw the icon
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CPaintDC dc(this);
  CDC dcBackBuffer;
  dcBackBuffer.CreateCompatibleDC(&dc);  
  //重新计算区域面积
  CRect rectClient;
  GetClientRect(rectClient);
  if ( m_sizeBuffer != rectClient.Size() )
  {
   m_sizeBuffer = rectClient.Size();
   if ( m_bmpBackBuffer.GetSafeHandle() != NULL )
    m_bmpBackBuffer.DeleteObject();
   m_bmpBackBuffer.CreateCompatibleBitmap(&dc, m_sizeBuffer.cx, m_sizeBuffer.cy);
  }
  CBitmap* pOldBmp = dcBackBuffer.SelectObject(&m_bmpBackBuffer);  

  //画背景
  if ( NULL == m_pbmpPattern )
  {  
   dcBackBuffer.FillSolidRect(rectClient, RGB(255,0,255));
  }
  else
  {
   CDC dcPat;
   dcPat.CreateCompatibleDC(&dcBackBuffer);
   CBitmap* pbmpOld = dcPat.SelectObject(m_pbmpPattern);
   BITMAP bitmap;
   if ( m_pbmpPattern->GetBitmap(&bitmap) && bitmap.bmWidth > 0 && bitmap.bmHeight > 0 )
   {
    BOOL m_bTilePattern ;
    m_bTilePattern =TRUE;
    if ( m_bTilePattern )
    {
     for (int y=0; y<rectClient.bottom+bitmap.bmHeight; y += bitmap.bmHeight)
     {
      for (int x=0; x<rectClient.right+bitmap.bmWidth; x += bitmap.bmWidth)
      {
       dcBackBuffer.BitBlt(x,y, bitmap.bmWidth, bitmap.bmHeight, &dcPat, 0,0, SRCCOPY);
      }
     }
    }
    else
    {
     dcBackBuffer.FillSolidRect(rectClient, RGB(255,0,255));
     dcBackBuffer.BitBlt((m_sizeBuffer.cx-bitmap.bmWidth)/2,(m_sizeBuffer.cy-bitmap.bmHeight)/2, bitmap.bmWidth, bitmap.bmHeight, &dcPat, 0,0, SRCCOPY);
    }
   }
   dcPat.SelectObject(pbmpOld);
  } 
  dc.BitBlt(0,0,m_sizeBuffer.cx,m_sizeBuffer.cy,&dcBackBuffer,0,0,SRCCOPY);  
  dcBackBuffer.SelectObject(pOldBmp);
  CDialog::OnPaint();
 }

现在我们的对话框就是真正利用了双缓冲来绘图性能比起第一个要好,而且还解决了闪烁问题

不用双缓冲实现无闪烁图象

首先说一下产生闪烁的原因,当窗口由于任何原因需要重绘时,总是先用背景色或背景图象将显示区清除,然后才显示图象,这样在短时间内背景色与显示图形交替出现,使得显示窗口看起来在闪。如果将背景刷设置成NULL...
  • ringphone
  • ringphone
  • 2007年12月03日 16:43
  • 5689

谈谈用MFC对话框做无闪烁图片重绘

在实现绘图的过程中,显示的图形总是会闪烁,笔者曾经被这个问题折磨了好久,通过向高手请教,搜索资料,问题基本解决,现将文档整理出来以供大家参考.1.显示的图形为什么会闪烁我们的绘图过程大多放在OnDra...
  • xdsoft365
  • xdsoft365
  • 2011年01月10日 11:41
  • 2352

MFC对话框-重绘非客户端区域(标题栏)

某些情况下需要在对话框标题栏上添加按钮,在此mark下: 环境:win7 + vs2008 + sp1 项目:MFC对话框 步骤:     1.  重写方法:DefWindowProc      ...
  • s123x456j789
  • s123x456j789
  • 2015年04月29日 16:04
  • 1891

在对话框中 实现重绘

1)  在对话框中重载重绘OnPaint() ,其中的CpaintDC dc(this) 是有自己的坐标系统的,看网络上说可以使用MapDialogRect 去掉模板单位到Screen单位。这个是在网...
  • zhoxier
  • zhoxier
  • 2012年05月17日 09:14
  • 6233

MFC中窗口重绘

2013-12-12 MFC提供了三个函数用于窗口重绘   ( 在刷新窗口时经常要调用重绘函数) InvalidateRect(&Rect) Invalidate() Up...
  • csunking
  • csunking
  • 2015年05月14日 21:51
  • 923

mfc标题栏重绘

1.mfc对话框 1.1 保留原标题栏 1.如果需要加高标题栏(用于贴图等),就要调用OnNcCalcSize追加部分空间(非客户区间): [cpp] view plai...
  • shenya1314
  • shenya1314
  • 2017年05月04日 17:14
  • 711

MFC隐藏窗口时解决窗口闪烁问题

MFC隐藏窗口时解决窗口闪烁问题
  • suyanfanhuameng
  • suyanfanhuameng
  • 2017年07月10日 17:04
  • 147

重绘按钮控件

在MFC中,对按钮控件进行重绘;通常的做法是:当按钮处于不同状态时,贴上相应的背景图片。 具体实现分四步: 1. 从CButton类派生一个子类CButtonEx 2. 重载虚函数Pre...
  • zwz1984
  • zwz1984
  • 2012年12月08日 10:32
  • 1235

VC++ - 窗口重绘

一、简单介绍 1、何时重绘?常见的无非两种情况: (1)产生无效区时,此时会受到WM_PAINT消息,这是必须重绘无效区。 (2)没有产生无效区,但是我就是想往窗口上写东西时。 ...
  • wajh07
  • wajh07
  • 2014年11月17日 15:40
  • 6305

MFC之窗口控件更新重绘相关函数

MFC窗口重绘需要知道的几个函数。Invalidate, InvalidateRect, UpdateData, UpdateWindow等。...
  • huanghuihuang1991
  • huanghuihuang1991
  • 2017年05月11日 10:37
  • 643
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用MFC对话框做无闪烁图片重绘
举报原因:
原因补充:

(最多只允许输入30个字)