龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > VC开发 >

VC防止窗口和控件闪烁的方法(2)

时间:2009-12-30 15:42来源:未知 作者:admin 点击:
分享到:
4、使用MemoryDC先在内存里把图画好,再复制到屏幕上 这对于一次画图过程很长的情况比较管用。毕竟内存操作比较快,而且复制到屏幕又是一次性的,至

  4、使用MemoryDC先在内存里把图画好,再复制到屏幕上

  这对于一次画图过程很长的情况比较管用。毕竟内存操作比较快,而且复制到屏幕又是一次性的,至少不会出现可以明显看出一个东东从左画到右的情况。

void CMyWin::OnPaint()
{
  CPaintDC dc1(this); // device context for painting
  dcMemory.CreateCompatibleDC(&dc1);
  CBitmap bmp;//这里的Bitmap是必须的,否则当心弄出一个大黑块哦。
  bmp.CreateCompatibleBitmap(&dc1,rectClient.Width(),rectClient.Height());
  dcMemory.SelectObject(&bmp);
  //接下来你想怎么画就怎么画吧。
  //dcMemory.FillRect(rectClient,&brush);
  dc1.BitBlt(0,0,rectClient.Width(),rectClient.Height(),&dcMemory,0,0,SRCCOPY);
  dcMemory.DeleteDC();
  // Do not call CWnd::OnPaint() for painting messages
}  争议
上述方法确实有效,但在有很多控件的情况下,计算一个窗口中需要擦除并重绘的“空白区域”是一件很麻烦的事情。为了方便这种方法的实际应用,我写了一组宏来完成”计算空白区域“的功能:

/*************************************************************************/
/************************************************************************/
/* 宏功能: 界面刷新时仅刷新指定控件以外的空白区域;可有效避免窗口闪烁
/* 使用于: WM_ERASEBKGND 消息处理函数 OnEraseBkgnd();
/************************************************************************/
#define ERASE_BKGND_BEGIN
CRect bgRect;
GetWindowRect(&bgRect);
CRgn bgRgn;
bgRgn.CreateRectRgnIndirect(bgRect);
//#define ERASE_BKGND_BEGIN
// Marco parameter 'IDC' specifies the identifier of the control
#define ADD_NOERASE_CONTROL(IDC)
{
  CRect controlRect;
  GetDlgItem(IDC)->GetWindowRect(&controlRect);
  CRgn controlRgn;
  controlRgn.CreateRectRgnIndirect(controlRect);
  if(bgRgn.CombineRgn(&bgRgn, &controlRgn, RGN_XOR)==ERROR)
   return false;
}
// Marco parameter 'noEraseRect' specifies a screen coordinates based RECT,
// which needn't erase.
#define ADD_NOERASE_RECT(noEraseRect)
{
  CRgn noEraseRgn;
  noEraseRgn.CreateRectRgnIndirect(noEraseRect);
  if(bgRgn.CombineRgn(&bgRgn, &noEraseRgn, RGN_XOR)==ERROR)
   return false;
}
// Marco parameter 'pDC' is a kind of (CDC *) type.
// Marco parameter 'clBrushColor' specifies the color to brush the area.
#define ERASE_BKGND_END(pDC, clBrushColor)
CBrush brush;
brush.CreateSolidBrush(clBrushColor);
CPoint saveOrg = (pDC)->GetWindowOrg();
(pDC)->SetWindowOrg(bgRect.TopLeft());
(pDC)->FillRgn(&bgRgn, &brush);
(pDC)->SetWindowOrg(saveOrg);
brush.DeleteObject();
//#define ERASE_BKGND_END
/*************************************************/

  说明:

精彩图集

赞助商链接