用户操作
[即时聊天] [发私信] [加为好友]
朱世武ID:raygtr
366次访问,排名2万外,好友0人,关注者0人。
raygtr的文章
原创 1 篇
翻译 0 篇
转载 0 篇
评论 24 篇
最近评论
文章分类
    收藏
      相册
      存档
      软件项目交易
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      原创 用MFC对话框做无闪烁图片重绘收藏

       | 

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

      把对话框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();
       }

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

      发表于 @ 2004年03月29日 10:26:00|评论(loading...)|编辑

       | 

      评论:没有评论。

      发表评论  


      当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
      Csdn Blog version 3.1a
      Copyright © raygtr