解決GDI閃屏問題

來源:互聯網
上載者:User

 

Introduction

Removing flicker from an MFC application is well-covered territory. You can find the topic addressed in books, and on-line. However, the techniques presented are somewhat complicated and are usually difficult to add to an existing application. One often-presented technique is called double buffering. Double buffering allows the new screen to be drawn in off-screen memory, and then the completed screen is bit-blited back onto the physical screen.

This article presents a class called CMemDC that encapsulates most of the issues associated with writing to off-screen buffers. Adding CMemDC to an existing application or MFC Active X control is nearly trivial.

Modifying an MFC Application to use CMemDC
  • Add the file memdc.h in your project.
  • Add the line #include "memdc.h" to stdafx.h.
  • Add a windows message handler for WM_ERASEBKGND.
  • Change the code in the message handler as follows: Collapse
    // Change this codeBOOL CExampleView::OnEraseBkgnd(CDC* pDC) {      // TODO: Add your message handler code here and/or call default      return CView::OnEraseBkgnd(pDC);} // To this codeBOOL CExampleView::OnEraseBkgnd(CDC* pDC) {      return FALSE;}
  • Change your OnDraw code to the following:

     Collapse
    void CExampleView::OnDraw(CDC* dc){    CMemDC pDC(dc);    CExampleDoc* pDoc = GetDocument();    ASSERT_VALID(pDoc);    // TODO: add draw code for native data here - use pDC      //as the device context to draw to}

Compile your code after you've made these changes and you will notice that the flicker you had seen before is gone.

Modifying a MFC Active X Control to use CMemDC

To add CMemDC support you follow the instruction for adding the support to an application, however you make one small change in the OnDrawfunction.

 Collapse
void CParticleTestCtlCtrl::OnDraw(CDC* pdc, const CRect& rcBounds,                                   const CRect& rcInvalid){    CMemDC pDC(pdc, &rcBounds);    // TODO: add draw code for native data here    // - use pDC as the device context to draw }

The only substantial difference is that the rcBounds is passed to the CMemDC constructor.

Source Code Collapse
#ifndef _MEMDC_H_#define _MEMDC_H_ //////////////////////////////////////////////////// CMemDC - memory DC//// Author: Keith Rule// Email:  keithr@europa.com// Copyright 1996-2002, Keith Rule//// You may freely use or modify this code provided this// Copyright is included in all derived versions.//// History - 10/3/97 Fixed scrolling bug.//               Added print support. - KR////       11/3/99 Fixed most common complaint. Added//            background color fill. - KR////       11/3/99 Added support for mapping modes other than//            MM_TEXT as suggested by Lee Sang Hun. - KR////       02/11/02 Added support for CScrollView as supplied//             by Gary Kirkham. - KR//// This class implements a memory Device Context which allows// flicker free drawing. class CMemDC : public CDC {private:           CBitmap    m_bitmap;        // Offscreen bitmap    CBitmap*       m_oldBitmap; // bitmap originally found in CMemDC    CDC*       m_pDC;           // Saves CDC passed in constructor    CRect      m_rect;          // Rectangle of drawing area.    BOOL       m_bMemDC;        // TRUE if CDC really is a Memory DC.public:        CMemDC(CDC* pDC, const CRect* pRect = NULL) : CDC()    {        ASSERT(pDC != NULL);          // Some initialization        m_pDC = pDC;        m_oldBitmap = NULL;        m_bMemDC = !pDC->IsPrinting();         // Get the rectangle to draw        if (pRect == NULL) {             pDC->GetClipBox(&m_rect);        } else {             m_rect = *pRect;        }         if (m_bMemDC) {             // Create a Memory DC             CreateCompatibleDC(pDC);             pDC->LPtoDP(&m_rect);              m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(),                                                   m_rect.Height());             m_oldBitmap = SelectObject(&m_bitmap);              SetMapMode(pDC->GetMapMode());              SetWindowExt(pDC->GetWindowExt());             SetViewportExt(pDC->GetViewportExt());              pDC->DPtoLP(&m_rect);             SetWindowOrg(m_rect.left, m_rect.top);        } else {             // Make a copy of the relevent parts of the current              // DC for printing             m_bPrinting = pDC->m_bPrinting;             m_hDC       = pDC->m_hDC;             m_hAttribDC = pDC->m_hAttribDC;        }         // Fill background         FillSolidRect(m_rect, pDC->GetBkColor());    }        ~CMemDC()          {                  if (m_bMemDC) {             // Copy the offscreen bitmap onto the screen.             m_pDC->BitBlt(m_rect.left, m_rect.top,                            m_rect.Width(),  m_rect.Height(),                  this, m_rect.left, m_rect.top, SRCCOPY);                                      //Swap back the original bitmap.             SelectObject(m_oldBitmap);                } else {             // All we need to do is replace the DC with an illegal             // value, this keeps us from accidentally deleting the              // handles associated with the CDC that was passed to              // the constructor.                           m_hDC = m_hAttribDC = NULL;        }           }        // Allow usage as a pointer        CMemDC* operator->()     {        return this;    }            // Allow usage as a pointer        operator CMemDC*()     {        return this;    }}; #endif
License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author
Keith Rule

Web Developer

 United States

Member

I work at Tektronix in Beaverton OR. I've been programming for fun since 1975 (I started while in a Computer Explorer Scout group in Spokane WA). I've been programming in C since 1979 and I've been working professionally since 1983. 

I really enjoy www.codeproject.com. It has saved me an incredible amount of time. I only hope my small contributions have given back some of what I've taken.

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.