我是否必须继续创建图形对象

Do I have to keep creating a Graphics object

我是一名老 delphi 程序员,我习惯于创建对象并一直使用它们以提高内存使用率。但是在 c# 中(也许是我见过的所有教程),你每次都用 new 创建东西(感谢垃圾收集器!!,让我来编码)..

无论如何,我正在尝试创建一个有很多绘图的设计软件。 我的问题是:我是否必须创建一个图形对象,或者在每个绘画事件中使用 protected override void OnPaint(PaintEventArgs e) e.Graphics .. 因为当我创建一个图形对象然后调整我绘制的控件的大小时,图形我创建的对象有裁剪问题,只绘制旧的矩形区域..

谢谢

每个 class 实现 IDisposable 的一般规则是尽快对其进行 Dispose()。确保您了解 using(...){} 语句。

对于在 WinForms (GDI+) 中绘图,最佳做法确实是使用 PaintEventArgs 中的 Graphics 对象。因为你没有创建那个,所以 not Dispose() 它。也不要藏起来。

如果您想在 表面上绘制 ,请始终使用 Paint 事件中的 Graphics 对象!

如果你想绘制到 Bitmap 中,你可以创建一个 Graphics 对象并根据需要使用它。

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

在您的情况下,您可能需要考虑一种混合方法:将旧的图形操作绘制到位图中,例如BackgroundImageImage 您的控件

Current/ongoing 绘图是在表面上完成的。这相当于将位图用作 缓存 ,因此您不必为每个小变化等

重绘大量动作

这与您的 undo/redo 实施密切相关。您可以设置一个限制并将之前的那些绘制到 Btimap 中,将之后的那些绘制到表面上..

PS:你也应该重新考虑你的GC态度。身边有它简单、高效并且是一种祝福。 (而且,是的,我已经完成了我对 TP&Delphi 的分享,回到他们负担得起的时候......) - 是的,我们进行编码,但 GC 不是关于编码而是关于内务管理。充其量无聊..(你总是可以设计来避免它,但不能在 windows 系统中使用 Graphics 对象。)

Caching objects makes sense when the object is expensive to create, cheap to store and relatively simple to keep updated. A Graphics object is unique in that none of these conditions are true:

  • It is very cheap to create, takes well less than a microsecond.
  • It is very expensive to store, the underlying device context is stored in the desktop heap of a session. The number of objects that can be stored is small, no more than 65535. All programs that 运行 in the session share that heap.
  • It is very hard to keep updated, things happen behind your back that invalidates the device context. Like the user or your program changing the window size, invalidating the Graphics.ClipBounds 属性. You are wasting the opportunity to use the correct Graphics object, the one passed to you in a Paint event handler. Particularly a bug factory when you use double-buffering.

Caching a Graphics object is a bug.

我必须完全不同意这里其他更有经验的成员的意见,他们说这没什么大不了的,或者实际上一遍又一遍地重新创建图形 object 更好。

HDC 是指向 HDC__ 结构的指针,该结构只有一个成员 "int unused"。每次需要绘制时创建另一个 instance/object 绝对是浪费和愚蠢。 HDC 并不大,它是 4 字节或 8 字节,它指向的结构几乎在所有情况下都是 4 字节。另外,就一个人做的这一点来说,在switch之前的WndProc()开头加上"static"关键字做图形object也无济于事,因为只有这样才能为 Graphics object 提供设备上下文或句柄以在其上绘制是通过调用其构造函数,因此 "static" 无法避免您一遍又一遍地创建它。

除此之外,Microsoft 建议您创建一个 HDC 指针并将其分配给 PAINTSTRUCT 已经具有的相同值,它发送的每条 WM_PAINT 消息。

很抱歉,我认为 WinAPI 非常糟糕。举个例子,我花了一整天研究如何制作 child WS_EX_LAYERED window,发现要启用 Win 8 功能,必须在 [=31] 中添加代码=] 将 OS 的 ID 号添加到清单中。太荒谬了。