我有一个表单,它在构造函数中设置这些样式:
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开发。
通过自己实现调整大小功能,我设法摆脱了大部分黑条纹。 Hovewer还有一些小问题。有没有办法立即执行resize
和paint
操作?这是我需要做的伪代码:
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上保持良好的空气动力效果。任何帮助都将深表感谢。
看起来这个问题无法解决,因为它在Windows上无所不在,在每个应用程序中都无法解决。我们可以希望MS在Mac OS X中获得一些灵感,并在新的Windows中提供适当的API。
答案 0 :(得分:1)
我找到了可以同时绘制和调整窗口大小的函数 - UpdateLayeredWindow
。
所以现在应该可以创建可调整大小的窗口,在调整大小时没有任何条带。但是,您需要自己绘制窗口内容,因此有点不方便。但我认为使用WPF
和UpdateLayeredWindow
时,应该没有任何问题。
发现问题。 :-)使用UpdateLayeredWindow
时,必须自己绘制窗口的边框。所以,如果你想在win7中使用UpdateLayeredWindow
绘制的标准窗口具有漂亮的玻璃效果,你就会被搞砸了。
On Microsft Connect甚至是一个关于这个问题的线索,微软称这是一个设计错误,如果它得到修复,那么可能在Win8或一些较新的系统中。所以我们无能为力。
答案 1 :(得分:0)
我发现最好不要直接在Form表面上进行任何自定义渲染。相反,在表单上放置一个停靠的PictureBox,创建将在PictureBox中显示的Bitmap对象,使用System.Drawing.Graphics.FromImage(Image)
方法将所有内容绘制到该对象上。
我使用游戏循环的方法来制作一个简单的射击游戏(Crimsonland风格)并且获得了相当不错的性能(使用抗锯齿线),超过100 FPS。