Like Tree1Likes
  • 1 Post By adeyblue

GDI+ and double buffering

This is a discussion on GDI+ and double buffering within the Windows Programming forums, part of the Platform Specific Boards category; Hi everyone! I've just started using GDI+, and I've got a program which updates the graphics whenever a timer ticks. ...

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    128

    GDI+ and double buffering

    Hi everyone! I've just started using GDI+, and I've got a program which updates the graphics whenever a timer ticks. It works fine, but it flickers annoyingly. I managed to use double buffering to solve this with GDI, but I don't know how to do this in GDI+.

    Here's the structure of my program:

    Code:
    void update (HDC hdc)
    {
       Graphics graphics(hdc);
       Pen black(Color(255, 0, 0, 0), 4);
       SolidBrush red(Color(255, 255, 0, 0));
       SolidBrush blue(Color(255, 0, 0, 255));
       SolidBrush orange(Color(255, 200, 200, 0));
       graphics.DrawLine(&black, 0, 530, GetSystemMetrics(SM_CXSCREEN), 530);
       graphics.DrawLine(&black, orangex+170, 530, orangex+170, 450);
       graphics.FillEllipse(&red, x, y, 50, 50);
       graphics.FillEllipse(&blue, bluex, bluey, 10, 150);
       graphics.FillEllipse(&orange, orangex, orangey, 150, 10);
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    
    	HDC hdc;
        PAINTSTRUCT ps;
    
        switch(msg)
        {
    
    		case WM_TIMER:
    			    //calculate new coordinates for the GDI objects.
    				InvalidateRect(hwnd, NULL, TRUE);
    				UpdateWindow(hwnd);
    			break;
    
    		case WM_PAINT:
                hdc = BeginPaint(hwnd, &ps);
    	        update(hdc);
                EndPaint(hwnd, &ps);
            break;
    Any help with getting rid of the flicker would be nice I appreciate it!

  2. #2
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    611
    You do it the same way, but instead of creating HDC's and HBITMAP's you create Graphics() & Bitmap(). To double-buffer, create a Bitmap the same size as the client area, create a Graphics based on that bitmap and do your drawing to that graphics object. When you've finished drawing, DrawImage() the bitmap to the main Graphics that's wrapping the dc.

  3. #3
    Registered User
    Join Date
    Feb 2010
    Posts
    128
    Thanks - I've changed it to this:

    Code:
    void update (HWND hwnd, HDC hdc)
    {
       RECT rc;
       GetClientRect(hwnd, &rc);
       Bitmap buffer(rc.right, rc.bottom);
       Graphics graphicsbuf(&buffer);
       Graphics graphics(hdc);
    
       Pen black(Color(255, 0, 0, 0), 4);
       SolidBrush red(Color(255, 255, 0, 0));
       SolidBrush blue(Color(255, 0, 0, 255));
       SolidBrush orange(Color(255, 200, 200, 0));
       graphicsbuf.DrawLine(&black, 0, 530, GetSystemMetrics(SM_CXSCREEN), 530);
       graphicsbuf.DrawLine(&black, orangex+170, 530, orangex+170, 450);
       graphicsbuf.FillEllipse(&red, x, y, 50, 50);
       graphicsbuf.FillEllipse(&blue, bluex, bluey, 10, 150);
       graphicsbuf.FillEllipse(&orange, orangex, orangey, 150, 10);
    
       graphics.DrawImage(&buffer, 0, 0);
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    
    	HDC hdc;
        PAINTSTRUCT ps;
    
        switch(msg)
        {
    
    	    case WM_COMMAND:
    			switch(LOWORD(wParam))
    			{
                                              //buttons which change some of the coordinates, drawn using CreateWindowEx with hwnd.
    			case IDC_RIGHT:
    				orangex = orangex + 20;
    				break;
    
    			case IDC_LEFT:
    				orangex = orangex - 20;
    				break;
    
    			}
    			break;
    
    
    		case WM_TIMER:
    			    //Update coordinates here
    				InvalidateRect(hwnd, NULL, TRUE);
    				UpdateWindow(hwnd);
    			break;
    
    		case WM_PAINT:
                hdc = BeginPaint(hwnd, &ps);
    	        update(hwnd, hdc);
                EndPaint(hwnd, &ps);
            break;
    ... but now, the flickering is even worse and it runs slower too - have I got it right (I'm guessing not!!). Thanks for your help yet again.

  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,856
    Handle WM_ERASEBKGND (just return true) and change the last param of InvalidateRect to FALSE.

    If that does not work, give your graphics object more scope (ie do the drawing BEFORE you call for a paint msg and not while the screen is 'waiting' to be redrawn within the paint msg).
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Double Buffering in mode 12h
    By j0seph in forum C Programming
    Replies: 6
    Last Post: 03-03-2005, 11:09 PM
  2. Double buffering in GDI -- easy?
    By fusikon in forum Game Programming
    Replies: 17
    Last Post: 02-15-2003, 09:03 PM
  3. double buffering for allegro
    By Leeman_s in forum C++ Programming
    Replies: 6
    Last Post: 09-12-2002, 02:45 PM
  4. Text && Double Buffering
    By GaPe in forum C Programming
    Replies: 2
    Last Post: 06-09-2002, 05:46 AM
  5. double buffering in MFC
    By Unregistered in forum Windows Programming
    Replies: 0
    Last Post: 03-07-2002, 11:29 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21