Win32 GDI Double Buffering

Hi. I want to use Double Buffering to a program I wrote.
This works like it should, but it looks bad

1
2
3
4
5
6
7
8
PAINTSTRUCT ps; 
RECT rect; 
GetClientRect(hwnd, &rect);
hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &rect, HBRUSH(GetStockObject(WHITE_BRUSH)));
DrawGrid(hdc, col, row, grid, hwnd);
EndPaint(hwnd, &ps);


So I figured out that using double buffering would be better and I tried this

1
2
3
4
5
6
7
8
9
PAINTSTRUCT ps;
RECT rect;
GetClientRect(hwnd, &rect);
hdc = BeginPaint(hwnd, &ps);
back_hdc = CreateCompatibleDC(hdc);
FillRect(back_hdc, &rect, HBRUSH(GetStockObject(LTGRAY_BRUSH)));
DrawGrid(back_hdc, col, row, grid, hwnd);
BitBlt(hdc, 0, 0, rect.right, rect.bottom, back_hdc, 0, 0, SRCCOPY);
EndPaint(hwnd, &ps);


But it doesn't work. It renders a white window.


The code above is placed in WindowProc function in WM_PAINT case.

The definition of DrawGrid is this

 
void DrawGrid(const HDC &hdc, const int &col, const int &row, const std::vector<std::vector<char> > &grid, const HWND &hwnd);


Thanks for helping.
Last edited on
CreateCompatibleDC function creates a DC that is 1 pixel wide by 1 pixel high (tiny) - and it is black and white.

You need to create a bitmap (using the CreateCompatibleBitmap function) of the size you really want - select it into this DC - this action will cause the DC to resize appropriately.
Last edited on
Allocation and cleanup gets tricky with WinGDI. Here's an example of how to do it properly:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//  TO ALLOCATE
// we'll make an 800x600 24-bit offscreen DC
HDC mdc = CreateCompatibleDC(NULL);
HBITMAP mbmp =  CreateBitmap(800,600,1,24,NULL); // width, height, 1, bit_depth, NULL
HBITMAP moldbmp = (HBITMAP)SelectObject(mdc,mbmp);


//  - now you can draw to/from mdc -


// TO CLEAN UP / DESTROY
SelectObject(mdc,moldbmp);
DeleteObject(mbmp);
DeleteDC(mdc);


Notes:

1) keeping track of moldbmp here is important for cleanup, even though you never use it

2) You can also use CreateCompatibleBitmap instead of CreateBitmap, but you need to give it a target DC, and you cannot use mdc or you'll get a monochrome bitmap. Instead you could use the display, but then you have to Get and Release the display DC, which is more of a hassle.

3) Don't create and destroy the above every time you draw. Create it once when the window opens, then destroy it when the window closes.

4) This kind of thing just begs to be objectified. You might want to strongly consider writing a class to wrap creating/destruction in the ctor/dtor so that you don't have to worry about forgetting to clean up.
Thank you. It's working now. :) I didn't know that I really need the HBITMAP thing.
Topic archived. No new replies allowed.