一、双缓冲原理及图解
(1)定义设备描述表及位图句柄
(2)创建一个与窗口矩形显示兼容的内存显示设备描述表,如图所示1步骤
(3)用hdc创建一个与窗口矩形显示兼容的位图,如图所示2步骤
(4)将位图hBitmap选入到内存显示设备hDCMem中,只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上,如图所示3步骤
(5)用hdc背景色将位图清除干净,如图所示4步骤
(6)绘图,如图所示5步骤
(7)将内存中的图拷贝到窗口矩形上进行显示,如图所示6步骤
下面是我写的俄罗斯方块简便中的一个画图函数:
void DrawBackGround(HDC hdc)
{
// char tmp[100];
HDC hMemDC;
int row, column, begin;
bool flag; // judge if the block are full of line
int left, top; // use to draw the block
static HBRUSH hBrush;
static HBITMAP hBitmap;
hBrush = CreateSolidBrush(RGB(255,255,255));
hMemDC = CreateCompatibleDC(hdc);
hBitmap = CreateCompatibleBitmap(hdc, WND_WIDTH+6, WND_HEIGHT+BLK_SIZE+1);
SelectObject(hMemDC, hBitmap);
FillRect(hMemDC, &ClientRect, hBrush);
MainFrame(hMemDC);
SelectObject(hMemDC, hBrush);
SelectObject(hMemDC, GetStockObject(WHITE_PEN));
begin = WND_ROWSIZE - 1;
for(row = WND_ROWSIZE - 1; row>=0; --row){
flag = false;
SelectObject(hMemDC, GetStockObject(WHITE_BRUSH));
/// Rectangle(hdc, 100, 100, 200, 200);
for(column = 0; column<WND_COLUMNSIZE; ++column){
top = row*BLK_SIZE + WND_OFFSET;
left = column*BLK_SIZE + WND_OFFSET;
if( !BlockMap[row][column]){
flag = true;
}
}
if( flag && begin>=0){
SelectObject(hMemDC, GetStockObject(GRAY_BRUSH));
for(column = 0; column<WND_COLUMNSIZE; ++column){
BlockMap[begin][column] = BlockMap[row][column]; /// record the block
if( BlockMap[begin][column] ){ change the position of row and column
left = column*BLK_SIZE + WND_OFFSET;
top = begin*BLK_SIZE + WND_OFFSET;
Rectangle(hMemDC, left, top, left+BLK_SIZE, top+BLK_SIZE);
}
}
begin --;
}
}
BitBlt(hdc, 0, 0, ClientRect.right-ClientRect.left,
ClientRect.bottom-ClientRect.top, hMemDC, 0, 0, SRCCOPY);
DeleteDC(hMemDC);
DeleteObject(hBrush);
DeleteObject(hBitmap);
}