Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8042077
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T04:27:03+00:00 2026-06-05T04:27:03+00:00

My GDI program runs fine on Windows XP but on Windows Vista and 7

  • 0

My GDI program runs fine on Windows XP but on Windows Vista and 7 it looks pretty terrible due to the lack of GDI hardware acceleration. I recall reading an article a few years back saying that Windows 7 added hardware acceleration to some GDI functions, including BitBlt() function. Supposedly, if you if you draw to a memory bitmap and then use BitBlt() to copy the image to your main window it runs about the same speed as XP. Is that true?

If it is true, how do you do it? I’m terrible at programming and am having a bit of trouble. I created the below class to to try and get it working:

class CMemBmpTest
{
private: 
    CDC         m_dcDeviceContext;
    CBitmap     m_bmpDrawSurface;

public:
    CMemBmpTest();
    ~CMemBmpTest();
    void Init();
    void Draw();
};

CMemBmpTest::CMemBmpTest()
{
}

CMemBmpTest::~CMemBmpTest()
{
    m_bmpDrawSurface.DeleteObject();
    m_dcDeviceContext.DeleteDC();
}

void CMemBmpTest::Init()
{  
    m_dcDeviceContext.CreateCompatibleDC(NULL);
    m_bmpDrawSurface.CreateCompatibleBitmap(&m_dcDeviceContext, 100, 100);
}

void CMemBmpTest::Draw()
{  
    m_dcDeviceContext.SelectObject(I.m_brshRedBrush);
    m_dcDeviceContext.PatBlt(0, 0, 100, 100, BLACKNESS);
}

In the OnPaint() function of the window I added the line:

pDC->BitBlt(2, 2, 100, 100, &m_MemBmp, 0, 0, SRCCOPY);

I was hoping to see a 100×100 black box in the corner of the window but it didn’t work. I’m probably doing everything horrifically wrong, so would be grateful if somebody could advise me as to how to do this correctly.

Thanks for any advice you can offer.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T04:27:05+00:00Added an answer on June 5, 2026 at 4:27 am

    AFAIK you get hardware acceleration on GDI functions on all versions of Windows (I’m happy to stand corrected on this if someone can explain it in more detail). But either way, you’re correct that double buffering (which is what you’re talking about) provides a massive performance boost (and more importantly no flickering) relative to drawing direct to the screen.

    I’ve done quite a lot of this and have come up with a method to allow you to use GDI and GDI+ at the same time in your drawing functions, but benefit from the hardware acceleration of the BitBlt in drawing to screen. GDI+ isn’t hardware accelerated AFAIK but can be very useful in many more complex drawing techniques so it can be useful to have the option of.

    So, my basic view class will have the following members :

    Graphics *m_gr;
    CDC *m_pMemDC;
    CBitmap *m_pbmpMemBitmap;
    

    Then the class itself will have code something like this

        /*======================================================================================*/
        CBaseControlPanel::CBaseControlPanel()
        /*======================================================================================*/
        { 
            m_pMemDC = NULL;
            m_gr = NULL;
            m_pbmpMemBitmap = NULL;
        }
    
        /*======================================================================================*/
        CBaseControlPanel::~CBaseControlPanel()
        /*======================================================================================*/
        {
            // Clean up all the GDI and GDI+ objects we've used
            if(m_pMemDC)
            { delete m_pMemDC; m_pMemDC = NULL; }
            if(m_pbmpMemBitmap)
            { delete m_pbmpMemBitmap; m_pbmpMemBitmap = NULL; }
            if(m_gr)
            { delete m_gr; m_gr = NULL; }
        }   
    
    /*======================================================================================*/
    void CBaseControlPanel::OnPaint()
    /*======================================================================================*/
    {
        pDC->BitBlt(rcUpdate.left, rcUpdate.top, rcUpdate.Width(), rcUpdate.Height(),
                            m_pMemDC, rcUpdate.left, rcUpdate.top, SRCCOPY);
    }
    
    /*======================================================================================*/
    void CBaseControlPanel::vCreateScreenBuffer(const CSize szPanel, CDC *pDesktopDC)
    // In : 
    //      szPanel = The size that we want the double buffer bitmap to be
    // Out : None
    /*======================================================================================*/
    {
        // Delete anything we're already using first
        if(m_pMemDC)
        {
            delete m_gr;
            m_gr = NULL;
            delete m_pMemDC;
            m_pMemDC = NULL;
            delete m_pbmpMemBitmap;
            m_pbmpMemBitmap = NULL;
        }
        // Make a compatible DC
        m_pMemDC = new CDC;
        m_pMemDC->CreateCompatibleDC(pDesktopDC);           
        // Create a new bitmap
        m_pbmpMemBitmap = new CBitmap;
        // Create the new bitmap
        m_pbmpMemBitmap->CreateCompatibleBitmap(pDesktopDC, szPanel.cx, szPanel.cy);
        m_pbmpMemBitmap->SetBitmapDimension(szPanel.cx, szPanel.cy);
        // Select the new bitmap into the memory DC
        m_pMemDC->SelectObject(m_pbmpMemBitmap);
        // Then create a GDI+ Graphics object
        m_gr = Graphics::FromHDC(m_pMemDC->m_hDC);
        // And update the bitmap
        rcUpdateBitmap(rcNewSize, true);
    }
    
    /*======================================================================================*/
    CRect CBaseControlPanel::rcUpdateBitmap(const CRect &rcInvalid, const bool bInvalidate, const bool bDrawBackground /*=true*/)
    // Redraws an area of the double buffered bitmap
    // In : 
    //      rcInvalid - The rect to redraw
    //      bInvalidate - Whether to refresh to the screen when we're done
    //      bDrawBackground - Whether to draw the background first (can give speed benefits if we don't need to)
    // Out : None
    /*======================================================================================*/
    {
       // The memory bitmap is actually updated here
    
       // Then make the screen update
       if(bInvalidate)
       { InvalidateRect(rcInvalid); }
    }
    

    So, you can then either just draw direct to the memory DC and call InvalidateRect() or put all your drawing code in rcUpdateBitmap() which was more convenient for the way I was using it. You’ll need to call vCreateScreenBuffer() in OnSize().

    Hopefully that gives you some ideas anyway. Double buffering is definitely the way to go for speed and non-flickering UI. It can take a little bit of effort to get going but it’s definitely worth it.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm attempting to display some text in my program using (say) Windows GDI and
I'm attempting to display some text in my program using (say) Windows GDI and
I know that GDI handles are unique and process specific in 'Big Windows' but
Say, I have a WPF program with a Windows Forms control in WindowsFormsHost on
I've written a simple GDI-based data plotter using C++/CLI but it's not particularly fast
I installed Windows 8 CP, and realized my program crashes on runtime: Unhandled exception
I've known about screen capture using Device Contexts and GDI, since windows XP. Is
In Windows XP the Win32 API renders the controls using GDI/GDI+. Now I'm on
Windows GDI has these functions: MoveTo(); LineTo(); They accept coordinates where to start drawing
Windows uses GDI to draw it's windows. Directx is way faster than GDI. Wouldn't

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.