2015-06-28 38 views
2

我是一位旧的delphi程序员,我习惯于创建对象并在整个时间内使用它们来实现高效的内存使用。但在C#(也许是所有的教程,我见过),你正在创造的东西与new每次(感谢垃圾回收!!,让我做的编码)..我是否需要继续创建一个图形对象

无论如何,我想创建一个有很多绘图的设计软件。 我的问题是:是否必须创建一个图形对象,或使用e.Graphics每个绘画事件..因为当我创建一个图形对象,然后调整我绘制的控件的大小时,我创建的图形对象,有剪辑的问题,只有老绘制的矩形区域..

感谢

+1

请始终使用提供的“Paint”方法。 CreateGraphics是一条确定的灾难之路。 – DonBoitnott

+1

好的感谢您的快速回答。我保留一个缓冲位图来绘制它,如果事情发生像调整大小或绘制额外的东西;我重绘了一个由它创建的图形对象,然后刷新它到一个控制组件的表面,其中的图形使用 graphics.DrawImage(bitmapB,0,0); 现在我将重新设计我的管道,并使用OnPaint事件的e.graphic对象来刷新..再次感谢。你真的很有帮助 –

回答

4

如果要在表面上画画请始终使用Paint事件中的Graphics对象!

如果你想绘制一个Bitmap你创建一个Graphics对象,并使用它,只要你想。

要使Paint事件生效,您需要收集图形操作List中的所有图形;所以你会想创建一个好的类来存储所有需要的参数。

在你的情况下,你可能想要考虑一种混合的方法:旧的图形动作绘制成位图, BackgroundImageImage您的控制

当前/正在进行的绘图在表面上完成。这相当于使用位图作为缓存,所以你不必重新绘制大量的行动,在每一个变化不大等

此密切相关的undo/redo实现。您可以设置一个限制,然后将这些绘制到Btimap中,然后绘制到表面上。

PS:您还应该重新考虑您的GC态度。这是简单,高效和周围的祝福。 (并且,是的,我已经完成了德尔福的TP &的分享,当他们负担的时候就回来了。) - 是的,我们做了编码,但GC不是关于编码,而是关于管家。镗最好..(你可以总是设计,以避免它,但不与一个Windows系统中的Graphics对象。)

2

对每个类别的一般规则,一旦实现IDisposable是Dispose()方法是,越好。确保你知道using(...){}声明。

对于在WinForms(GDI +)中绘图,最好的做法是使用PaintEventArgs中的Graphics对象。并且因为你没有创建那个,请执行而不是处理()它。不要把它藏起来。

7

缓存对象是有意义的,当对象是昂贵的创建,便宜的存储和相对简单保持更新。图形对象是在没有独特的这些条件为真:

  • 这是很便宜的创建,需要超过一微秒好少。
  • 存储非常昂贵,底层设备上下文存储在会话的桌面堆中。可以存储的对象数量很少,不超过65535个。会话中运行的所有程序共享该堆。
  • 保持更新非常困难,事情发生在背后,使设备环境无效。像用户或您的程序更改窗口大小,使Graphics.ClipBounds属性无效。您正在浪费使用正确的Graphics对象的机会,该对象是在Paint事件处理程序中传递给您的。特别是使用双缓冲时的错误工厂。

缓存图形对象是一个错误。

0

我不得不完全不同意这里的其他更有经验的成员,他们说这没什么大不了的,或者实际上反复重新创建Graphics对象。

HDC是一个指向HDC__结构的指针,它是一个具有一个成员“int unused”的结构。每次绘制需要完成时创建另一个实例/对象是绝对浪费和愚蠢的。 HDC不大,它可能是4或8字节,它指向的结构几乎在所有情况下都是4字节。此外,就一个人而言,在开关之前的WndProc()的开始处使用“static”关键字来制作图形对象并无帮助,因为唯一的方法是给图形对象一个设备上下文或句柄是通过调用它的构造函数来实现的,因此“静态”不会让您无法一次又一次地创建它。

最重要的是,Microsoft建议您创建一个HDC指针,并将其分配给PAINTSTRUCT已经具有的每个单个WM_PAINT消息发送的相同值。

对不起,但我认为WinAPI非常糟糕。举一个例子,我花了整整一天的时间研究如何创建一个WS_EX_LAYERED窗口,以发现为了启用Win 8功能,必须使用操作系统的ID号将XML代码添加到清单中。太可笑了。

相关问题