想做一个关于五子棋的程序,自己定义了一个函数DrawBoard用来画棋盘,可是执行完,棋盘怎么会一闪一闪的,不过闪不是很厉害,但还是让人受不了,请高手帮忙解决,函数定义如下:
void CPenteDlg::DrawBoard()
{
CClientDC dc(this); CBrush BoardBrush(RGB(0,255,0));
CPen pen(PS_SOLID,1,RGB(33,65,96));
dc.SelectObject(BoardBrush);
dc.SetROP2(R2_COPYPEN);
dc.Rectangle(m_rtBoard.left-FIVE_WIDTH/2,
m_rtBoard.top-FIVE_HEIGHT/2,
m_rtBoard.right+FIVE_WIDTH/2,
m_rtBoard.bottom+FIVE_HEIGHT/2);
CRgn rgn;
rgn.CreateRectRgn(m_rtBoard.left-FIVE_WIDTH/2,
m_rtBoard.top-FIVE_HEIGHT/2,
m_rtBoard.right+FIVE_WIDTH/2,
m_rtBoard.bottom+FIVE_HEIGHT/2);
dc.FillRgn(&rgn,&BoardBrush); dc.SelectObject(&pen);
for(int i=0;i<18;i++)
for(int j=0;j<18;j++)
dc.Rectangle(m_rtBoard.left+FIVE_WIDTH*i,
m_rtBoard.top+FIVE_HEIGHT*j,
m_rtBoard.left+FIVE_WIDTH*(i+1),
m_rtBoard.top+FIVE_HEIGHT*(j+1));
dc.SelectStockObject(BLACK_BRUSH);
}
void CPenteDlg::DrawBoard()
{
CClientDC dc(this); CBrush BoardBrush(RGB(0,255,0));
CPen pen(PS_SOLID,1,RGB(33,65,96));
dc.SelectObject(BoardBrush);
dc.SetROP2(R2_COPYPEN);
dc.Rectangle(m_rtBoard.left-FIVE_WIDTH/2,
m_rtBoard.top-FIVE_HEIGHT/2,
m_rtBoard.right+FIVE_WIDTH/2,
m_rtBoard.bottom+FIVE_HEIGHT/2);
CRgn rgn;
rgn.CreateRectRgn(m_rtBoard.left-FIVE_WIDTH/2,
m_rtBoard.top-FIVE_HEIGHT/2,
m_rtBoard.right+FIVE_WIDTH/2,
m_rtBoard.bottom+FIVE_HEIGHT/2);
dc.FillRgn(&rgn,&BoardBrush); dc.SelectObject(&pen);
for(int i=0;i<18;i++)
for(int j=0;j<18;j++)
dc.Rectangle(m_rtBoard.left+FIVE_WIDTH*i,
m_rtBoard.top+FIVE_HEIGHT*j,
m_rtBoard.left+FIVE_WIDTH*(i+1),
m_rtBoard.top+FIVE_HEIGHT*(j+1));
dc.SelectStockObject(BLACK_BRUSH);
}
{
CDC dc;
CBitmap bmp;
CRect tRct;
CClientDC fdc(this);
GetClientRect(&tRct); dc.CreateCompatibleDC(&fdc);
bmp.CreateCompatibleBitmap(&fdc,tRct.Width(),tRct.Height());
dc.SelectObject(&bmp); CBrush BoardBrush(RGB(0,255,0));
CPen pen(PS_SOLID,1,RGB(33,65,96));
dc.SelectObject(BoardBrush);
dc.SetROP2(R2_COPYPEN);
dc.Rectangle(m_rtBoard.left-FIVE_WIDTH/2,
m_rtBoard.top-FIVE_HEIGHT/2,
m_rtBoard.right+FIVE_WIDTH/2,
m_rtBoard.bottom+FIVE_HEIGHT/2);
CRgn rgn;
rgn.CreateRectRgn(m_rtBoard.left-FIVE_WIDTH/2,
m_rtBoard.top-FIVE_HEIGHT/2,
m_rtBoard.right+FIVE_WIDTH/2,
m_rtBoard.bottom+FIVE_HEIGHT/2);
dc.FillRgn(&rgn,&BoardBrush); dc.SelectObject(&pen);
for(int i=0;i<18;i++)
for(int j=0;j<18;j++)
dc.Rectangle(m_rtBoard.left+FIVE_WIDTH*i,
m_rtBoard.top+FIVE_HEIGHT*j,
m_rtBoard.left+FIVE_WIDTH*(i+1),
m_rtBoard.top+FIVE_HEIGHT*(j+1));
dc.SelectStockObject(BLACK_BRUSH); fdc.BitBlt(0,0,tRct.Width(),tRct.Height(),&dc,0,0,SRCCOPY);
}
棋子移动时只要重绘移动前和移动后的区域就行了用 InvalidateRect
2,如果每次重绘要做的动作非常多,使用Memory dc,把所有的动作画到内存中然后再真正画到屏幕上(两点注意:其一,兼容位图的大小有限制,不够大的话用DIB段;其二,兼容位图创建出来之后底色是黑色的,一定要刷底色先;其三,如果每次绘制的工作量不大,闪烁是因为其他原因引起的,此方法不会有多大效果)
3,映射WM_ERASEBKGND消息,直接return TRUE(大部分的闪烁都是因为这个原因引起的,原因是windows默认情况下在绘制之前先把底色刷成白色,然后再做程序中的绘制动作,但是要注意这个方案最好和memory dc一起用,否则你会发现旧的图案可能没有擦掉,屏幕一团糟。)