【问题标题】:WPF: GDI drawing in other process flickersWPF:其他进程中的GDI绘图闪烁
【发布时间】:2014-06-21 01:38:02
【问题描述】:

有很多关于 GDI 绘图和闪烁问题的主题,但我还没有找到任何关于在其他进程中绘图的主题。

问题

基本上我正在尝试使用 Graphics.FromHwnd 绘制到 Hwnd。这完美地工作,但涉及很多闪烁。我正在尝试绘制的应用程序是一个游戏(不是我制作的),并且具有相当高的刷新率,与表单不同。

尝试

我尝试过使用 GDI.Rectangle 函数进行绘图,该函数使用 HDC 进行绘制,并使用 Graphics.DrawRectangle 绘制到 Hwnd。我没有注意到性能上的差异,但“图形”似乎更容易使用,因为它不需要 gdi32.dll 来绘制形状,这与 GDI 不同。

我也尝试过双缓冲,但我还是没有发现任何区别。

对我来说,双缓冲似乎不起作用,因为我试图在如此高的刷新率窗口中进行绘制。

问题

  • 是否可以获取窗口的刷新率并将其用于计时器来更新图形?
  • 是否可以让图形在更新之前一直保持不变,这样它们就不会自动消失?

如果有人知道如何做到这一点,或者知道其他解决方案来摆脱闪烁,我将不胜感激!

提前致谢。

【问题讨论】:

  • 这是 abpit WPF 吗?不是GDI+吗?无论如何,您是如何尝试双缓冲的?它必须在目标应用程序上完成(至少与 GDI 设备上下文关联的窗口应该具有 WS_EX_COMPOSITED 窗口样式)。
  • @Adriano “这不是 GDI+ 吗?”:老实说我不知道​​......我以为我在使用 GDI,但经过一些研究,我认为我实际上在使用 GDI+。我要检查是否可以将其更改为 GDI 以在那里运行一些测试。如果可能的话,我想我可能会尝试在游戏窗口上设置 WS_EX_COMPOSITED。我会在下班回家后立即尝试并发布结果。
  • 我已经在游戏窗口中设置了 WS_EX_COMPOSITED。它确实减少了一点闪烁,但仍然有相当数量。我认为这是因为我正在使用计时器进行绘图。是否可以为游戏窗口的绘图事件做一个钩子之类的东西?
  • 我认为你应该发布一些代码,GDI+ 本身很慢,我认为一些一般性的建议对你没有帮助。例如,如果您为每个绘画事件创建资源(如画笔),这会大大降低性能。此外,计时器可能是(或不是)一个好的解决方案,但为了保持高刷新率,您可能会在每次绘画后使窗口无效(以“模拟”例如在 DirectX 中使用的绘画循环)。
  • 好的,如果我找到解决方案或决定使用透明窗口,我会进行研究并回复。感谢您迄今为止的帮助!

标签: c# gdi+ gdi


【解决方案1】:

经过一些研究,我得出结论,使用透明窗口最适合我的情况。我是这样得出这个结论的:

我使用了一个应用程序来读取窗口事件,以检查是否有任何可能是窗口失效的连续事件流,但没有。

我确实找到了一种方法,可以在游戏使窗口无效时实际读取,但这有点像黑客:可以用你自己的替换游戏的 d3d9.dll 文件,调用所有原始函数,但捕捉事件。我不知道它是如何工作的,甚至它是否工作的任何细节,因为必须将 dll 分发给最终用户不是我的选择,更不用说这实际上是黑客攻击。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-22
    • 2011-11-22
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    相关资源
    最近更新 更多