调整窗口大小会导致黑条

时间:2010-04-10 13:00:59

标签: c# .net windows windows-7 flicker

我有一个表单,它在构造函数中设置这些样式:

this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

我在Paint事件中绘制了一些矩形。表单上没有控件。 Hovewer,当我调整表格大小时,表格右下方有黑条。有没有办法摆脱它们?我已经尝试了所有内容,在WM_ERASEBKGND中搜索WndProc,在WM_PAINT上手动绘制表单,实现自定义双缓冲区等等。还有什么我可以尝试的吗?

我发现了这个: https://connect.microsoft.com/VisualStudio/feedback/details/522441/custom-resizing-of-system-windows-window-flickers 它看起来像是DWM中的一个错误,但我希望我能做一些解决方法。

请注意,我必须使用双缓冲,因为我想在Paint事件中绘制非常强烈的图形显示。我使用C#.NET 2.0,Win7开发。

状态更新1

通过自己实现调整大小功能,我设法摆脱了大部分黑条纹。 Hovewer还有一些小问题。有没有办法立即执行resizepaint操作?这是我需要做的伪代码

IntPtr hDC;
var size = new Size(250, 200);
IntPtr handle = API.PaintAndResizeBegin(this.Handle /* Form.Handle */,
                                        size.Width, size.Height, out hDC);
using (var g = Graphics.FromHdc(hDC)) {
    this.backBuffer.Render(g, size);
}
API.PaintAndResizeCommit(handle);

有没有办法实现上面的代码?

第二种解决方案可能是对整个表单进行反向缓冲,包括非客户区域。但是怎么做呢?我不想自己绘制非客户区域,因为我想在Vista / 7上保持良好的空气动力效果。任何帮助都将深表感谢。

状态更新2

看起来这个问题无法解决,因为它在Windows上无所不在,在每个应用程序中都无法解决。我们可以希望MS在Mac OS X中获得一些灵感,并在新的Windows中提供适当的API。

2 个答案:

答案 0 :(得分:1)

我找到了可以同时绘制和调整窗口大小的函数 - UpdateLayeredWindow

所以现在应该可以创建可调整大小的窗口,在调整大小时没有任何条带。但是,您需要自己绘制窗口内容,因此有点不方便。但我认为使用WPFUpdateLayeredWindow时,应该没有任何问题。


更新

发现问题。 :-)使用UpdateLayeredWindow时,必须自己绘制窗口的边框。所以,如果你想在win7中使用UpdateLayeredWindow绘制的标准窗口具有漂亮​​的玻璃效果,你就会被搞砸了。

On Microsft Connect甚至是一个关于这个问题的线索,微软称这是一个设计错误,如果它得到修复,那么可能在Win8或一些较新的系统中。所以我们无能为力。

答案 1 :(得分:0)

我发现最好不要直接在Form表面上进行任何自定义渲染。相反,在表单上放置一个停靠的PictureBox,创建将在PictureBox中显示的Bitmap对象,使用System.Drawing.Graphics.FromImage(Image)方法将所有内容绘制到该对象上。

我使用游戏循环的方法来制作一个简单的射击游戏(Crimsonland风格)并且获得了相当不错的性能(使用抗锯齿线),超过100 FPS。