使用GDI +和C ++减少闪烁

时间:2008-10-13 15:16:16

标签: c++ windows gdi+

我在C ++ / MFC应用程序中使用GDI +,只要窗口调整大小,我似乎无法避免闪烁。

我已经尝试过这些步骤:

  • OnEraseBkGnd();
  • 上返回TRUE
  • OnCtlColor();
  • 上返回NULL
  • 根据此代码使用双缓冲:

void vwView::OnDraw(CDC* pDC) 
{
   CRect rcClient;
   GetClientRect(rcClient);

   Bitmap bmp(rcClient.Width(), rcClient.Height());
   Graphics graphics(&bmp);

   graphics.DrawImage(m_image, rcClient.left, rcClient.top);

   Graphics grph(pDC->m_hDC);
   grph.DrawImage(&bmp, 0, 0);
}

我做错了吗?或者还有另一种方法来实现这一目标吗?

6 个答案:

答案 0 :(得分:40)

答案 1 :(得分:4)

您可能会尝试使用老式的GDI而不是GDI +来写入DC,特别是因为您已经在缓冲图像。使用Bitmap :: LockBits访问原始位图数据,创建BITMAPINFO结构,并使用SetDIBitsToDevice显示位图。

答案 2 :(得分:3)

确保窗口的窗口类不包含其样式中的CS_VREDRAW和CS_HREDRAW标志。

请参阅http://msdn.microsoft.com/en-us/library/ms633574(VS.85).aspx

答案 3 :(得分:3)

您可以通过Direct3D使用"告诉"你在vsync发生时等等,所以你可以在适当的时候进行BitBlt /更新。请参阅 GDI vsync to avoid tearing (虽然将事情简化为一个小的BitBlt可能是"足够好"在某些情况下)。

另请注意,GDI BitBlt似乎与屏幕vsync不同步。请参阅 Faster than BitBlt

另请注意,使用CAPTUREBLT(允许您捕获透明窗口)会导致鼠标闪烁(如果未使用aero)(如果使用的话)。

答案 4 :(得分:2)

此链接包含一些有用的信息: http://www.catch22.net/tuts/flicker-free-drawing

(我知道这是一个非常晚的线程添加,但这适用于任何人(像我一样)在寻找减少我的Win32应用程序中的闪烁时找到它...)

答案 5 :(得分:0)

表格上是否有儿童窗户?窗口管理器首先通过发送WM_ERASEBKGND消息让父窗口擦除其背景,然后它发送一条wM_PAINT消息 - 大概这会映射到你的wx :: OnDraw方法。然后它迭代每个子控件并让它们自己绘制。

如果这是您的情况......使用Vistas新的aero外观将解决您的问题,因为aero桌面窗口管理器会自动执行窗口合成。旧的窗口管理器是一个皮塔饼。