【问题标题】:mouse movements for background thread created windows forms用于后台线程创建的 Windows 窗体的鼠标移动
【发布时间】:2014-05-30 01:17:54
【问题描述】:

我想知道是否可以 1) 在应用程序主线程创建的窗体中托管一个后台线程创建的窗体? 或 2) 将处理鼠标移动的线程与绘制窗体应用程序的线程分开?

我知道这些问题听起来很疯狂,但我发现自己遇到了一个特殊的问题,我欢迎能够回避这个问题的建议,尽管我认为我们不能轻易脱离 Windows 窗体并使用不同的 ui 技术.

我们的软件团队为第 3 方 Windows 窗体应用程序编写了一些插件。因此,我们提供了一个根主窗体,它使用他们的 api 向他们托管一堆用户控件,并且他们以自己的 windows 窗体托管它们。目前,所有用户界面都是在应用程序的主线程上创建的,因此它们可以很好地相互配合。我们提供的许多用户控件都有 system.windows.forms.datavisualisation 图表,这些图表由应用程序获取的数据实时绘制。我们遇到的问题之一是当用户不规律地移动鼠标时,显示停止更新,因为所有图形的绘制 (GDI+) 都是在主线程上完成的(我们使用后台线程和 TPL 来获取和计算数据,但是绘制在主线程上完成)。所以我想知道是否有可能让这些图表的所有 gdi+ 绘制发生在与应用程序主线程不同的线程上,所以绘制将继续,我们仍然可以接收鼠标移动输入和用户交互的点击,但是鼠标不稳定移动不能淹没消息队列并停止用户控件的 gdi+ 绘制。

任何特别的帮助,特别是指向相关 api 或演示技术的文章的指针将不胜感激。 谢谢。

【问题讨论】:

  • 匿名投票很糟糕,而且很懦弱。 :-)
  • 同意,+1 以补偿 :)

标签: multithreading winforms winapi mouse mschart


【解决方案1】:

这取决于抽签完成时减速的原因。

首先,您应该优化您的绘图例程,也许您在每次调用 OnPaint 时都在绘制整个表单/控件?如果是这种情况,那么您应该只重新绘制无效区域,这将大大加快速度。

否则,如果你还需要在另一个线程上绘制,那么你不能直接这样做,ui只能在主线程上修改,但你可以使用位图作为离屏缓冲区,然后从中重新绘制.

为此,当您创建控件时,您还会创建控件大小的位图(您也应该注意调整大小)。因此,当必须对控件的外观进行任何更改时,将其绘制到位图上,您可以在另一个线程中进行,然后使控件的更新区域无效。

最后,在您的控件的 OnPaint 中,只是从该位图传输到您的控件,并且只有无效区域,此调用仍将在主线程上完成,但我向您保证,今天的任何机器都能够传输非常大的图像毫秒。

例如,假设您有一个控件,您可以在其中绘制渐变背景和圆形。

通常,每次您想要更新某些内容(比如背景)时,您将通过 Graphics 对象直接绘制到控制表面,因此,要更改它,您将绘制完整的背景并在其上绘制圆圈。

要在后台执行此操作,如果您将位图创建为屏幕外缓冲区,则不会绘制到表面,而是在另一个线程中绘制到位图(从中获取图形对象),然后使更新的区域无效的控制。当您使该区域无效时,将调用 OnPaint,然后您可以从该位图 blit 到控件表面。

在这一步中,您几乎没有获得任何速度,但让我们扩展我们的示例。假设您正在绘制一个非常复杂的控件,其中有很多对 DrawImage、DrawCircle 等的调用。 当鼠标移到控件上时,小区域会失效,并且在每次 OnPaint 调用中,您将绘制构成失效区域的所有“层”,如果如我们所说的控件非常复杂,则可能需要进行大量绘制。

但是,如果您确实将控件外观绘制到位图,则在每次 OnPaint 调用时,您只需将位图的相应区域 blit 到控件,正如您所见,您正在将大量绘制的调用减少到仅 blit。

希望它能澄清这个想法。

【讨论】:

  • 感谢您的建议。我们确实使用后台线程和 blit 渲染到后台缓冲区,就像您提到的自定义绘制屏幕一样,以及选择性失效,但是,根窗口窗体的双缓冲属性设置为 true,我认为所有用户控件也是如此,也许这是适得其反,如果这意味着后台缓冲区太多,您有什么建议吗?我的 windows 窗体控件和 mscharts 也完成了很多绘画我不确定如何让它们在位图​​上绘画并在使用双缓冲属性的情况下进行 blit 是否可能?
  • 扩展答案以澄清概念。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多