如何高效渲染双缓冲窗口,没有任何撕裂效果?

时间:2012-03-27 12:41:55

标签: c++ user-interface custom-controls gdi+

我想创建自己的小型无窗口GUI系统,因为我正在使用GDI +。我不能在这里发布代码因为它很大(c ++)但是下面是我正在遵循的主要步骤......

  1. 创建一个大小等于应用程序窗口的位图。
  2. 对于所有鼠标和键盘事件,更新自定义控件状态(例如,如果鼠标当前保持在特定控件e.t.c上。)
  3. 对于WM_PAINT事件,将背景绘制到屏幕外位图,然后在其上绘制所有更新的控件,最后通过Graphics :: DrawImage(..)调用将整个屏幕外图像复制到前缓冲区。
  4. 对于WM_SIZE / WM_SIZING,删除先前的屏幕外位图并创建另一个具有新窗口大小的位图。
  5. 还有一些检查可以防止重复绘制控件,即只有在需要重新绘制时才会绘制控件,换句话说,当控件的状态发生变化时,它才被绘制为e.t.c.

    系统工作正常但只有一个例外......当窗口正在调整大小时会出现某种撕裂效果。我的意思是撕裂效果我会试着解释......

    在调整边缘/边框上,当我拖动边框时有一个闪烁的间隙。就好像我的DrawImage()函数立即返回,而一次交换操作完成一半时,另一个图像绘制开始。

    现在您可能认为在许多其他应用程序中发生的常见工件是因为调整后台缓冲区并不总是像调整窗口大小一样快但是在其他应用程序中我注意到在其他应用程序中虽然窗口之间有一条腿大小和客户区域大小随着窗口大小的增加,边缘附近没有任何闪烁(通常只是白色背景,沿着边界显示为细的均匀条带)。 此外,随着窗口大小调整而移动的动态控件在调整大小时会出现抖动。

    起初我觉得在屏幕外使用恒定的全屏尺寸可以最大限度地减少伪影,但是当我尝试它时,结果并不令人满意。我还尝试在调整大小时调用Sleep(),以便在另一次翻转开始之前完全翻转,但奇怪的是,这对我来说无效!

    我听说过Vista上的GDI不是硬件加速的,这可能是问题吗?

    此外,我想知道像Qt这样的框架如何如此平滑地呈现无窗口GUI,即使你非常快速地调整复杂的Qt GUI窗口,也几乎看不到很少的工件。据我所知,Qt可以使用opengl进行GUI渲染,但这是第二种选择。

    如果我使用directx那么实时调整大小就更难了,另一方面,opengl似乎很适合调整大小而没有任何问题,但是我将放弃GDI +的所有2D绘图功能。

    如果你们之前有过这样的事情,请指导我。此外,如果您有自定义用户界面设计应考虑的任何指针,请提供链接。

    谢谢!

    我一直希望设计像windows media player 11这样的接口,但是有人可以告诉我c ++程序员有一个直接的解决方案(我想知道如何而不是使用现有的框架等)?子类,所有者绘图,自定义绘图似乎没有给你这样的控制水平,我不知道用常见控件绘制半透明控件的方法,所以我认为这个问题值得特别注意。再次感谢。

1 个答案:

答案 0 :(得分:5)

它是否是导致它的WM_ERASEBKGND消息?

请参阅此问题:GDI+ double buffering in C++

此外,如果您需要从GUI快速响应,我会建议不要使用GDI +。