2010-10-14 34 views
1

好的,我相信你们中的一些人已经知道我的头衔发生了什么,因为我得到这是非常常见的问题。但我的问题其实更深一些,所以请耐心等待我。C#绘图消失(实际上是更多的系统问题)

我所有的编程我在过去几年所做均汇编,主要是8051和AVR作为WEEL在C,同时也为微控制器。 HW比SW更令我着迷。但我也对操作系统及其API等功能着迷。几天后,我告诉我的朋友说,如果你有数学解析器,创建一个非常简单的程序来绘制函数图应该很容易。他不相信我,所以我试图做出一个。

我决定用C#去,即使我不知道OOP。但我想,如果我得到的一切都在一个按钮动作完成它会像好老C.

所以我得到的数学解析器的工作,而且比开始使用Pen对象绘制。我的第一个尝试是绘制简单的线条。阅读完一篇教程之后,我创建了一个简单的坐标轴。

但是,比我注意到一些奇怪的事情,当我简化了我的程序,绘制消失。这让我想起了关于这个所有绘图是如何在系统级完成的。

我认为系统保持活动窗口的图像,直到其更改。所以当你移动你的窗户时,它只会改变它在famebuffer中的位置。当你最小化它时,它会在drawind中跳到framebuffer。

但我看到它不是这样的。所以,请你能告诉我为什么会发生这种情况?我可以在许多教程中阅读如何防止它,但我想知道更多原因。更多的是,这是由于系统API的工作原理,或者因为C#绘图类的工作原理。

此外,这使我想到在C#和.NET库是什么功能那只是呼吁WinAPI的函数,它的工作原理完全一样的方式,以及如何许多图书馆和功能做更多的事情。就像在GDI中没有绘制线的功能一样,并且只能绘制点,那么C#会添加从此点绘制线的功能。我希望你能理解我。

谢谢。

+1

我猜它来自当内存是昂贵的时间。从历史的角度来看,这可能是一个更好的主意,当应用程序被遮挡时,应用程序会重新绘制窗口,而不是将每个窗口的内容的副本保存在单独的内存缓冲区中,以备需要时使用。如果窗口的内容大部分是背景,或者图像是通过绘制基元而不是栅格来构建的,则尤其如此。 – 2010-10-14 22:21:51

回答

5

这是它在Win32 API中的工作原理。当窗口最小化时,它所占用的区域变得“无效”,所以windows系统知道屏幕的这个区域需要重绘。这导致WM_PAINT消息被发送到负责绘制该区域的窗口程序。您可以阅读更多关于使客户区(您的程序负责的区域)无效的信息here

如果您对这些东西真正感兴趣并希望深入了解系统如何处理绘图(以及其他事情,如Windows消息),我建议您阅读更多关于Win32 API的内容,例如从Charles Petzold的经典作品Programming Windows开始。

0

如果要绘图,请使用Microsoft图表控件。 http://www.microsoft.com/downloads/en/details.aspx?FamilyId=130F7986-BF49-4FE5-9CA8-910AE6EA442C&displaylang=en

或ZedGraph http://zedgraph.org/

如果你想绘制自己:该窗口重绘时您调整。
您需要在重绘事件或任何被调用的事件上重绘您的绘图。
这是完全正常的。

另外,使用.NET 4.0,否则,除非删除(重绘)所有内容,否则不可能删除以编程方式绘制的任何内容。

1

在Windows中(在Vista/DWM和MIL之前),应用程序负责绘制自己的GUI。也就是说,当操作系统告诉应用程序这样做时,应用程序必须绘制自己的GUI。调整大小或移动表单将触发绘画事件。这是它在User32 + GDI中的工作原理。也就是说,应用程序绘制自己的像素。

然而,WPF应用程序将使用媒体集成层(Vista和Windows 7),“mil核心”负责绘制应用程序的可视化树。在这种情况下,操作系统负责渲染,但应用程序负责渲染它的内容。

2

你的绘画并没有消失,它根本就不存在。与我同行:

  • 要在Windows窗口上绘图,您必须响应WM_PAINT消息指示的回调。这是在Win 3.11,现在是如此。
  • 借鉴点击按钮是在浪费时间,因为一个表单/控制/窗口重画会画背景颜色有
  • 移动从按钮事件处理函数相同的代码来OnPaint - 当然,处理在语义
  • 的差异
  • 窗口不会保存您的屏幕缓冲区的副本 - 绘图 - 所以你必须保存在某个地方,或绘制在即时