忽略 VM_ERASEBKGND from paint event 每次在 winform off-screen 上都不起作用,为什么?

Ignoring VM_ERASEBKGND from paint event does not work every time on winform off-screen why?

我有一个 windows 表单应用程序,可以在其前面绘制图像和几何图形。当我将 windows 表单拖出屏幕并将其带回屏幕时出现问题,使屏幕外的部分全部清除。

我读到这可能是因为 windows 消息发送到我的应用程序 VM_ERASEBKGND 并清除屏幕外的部分。 (我说得对吗?)

所以首先,我创建了一个只显示图像的测试应用程序,我覆盖了在这种情况下有效的 WndProc 方法,这里是如何实现的:

protected override void WndProc(ref System.Windows.Forms.Message m)
  {
     switch (m.Msg)
     {
         //0x0014 reprensts VM_ERASEBKGND message
        case 0x0014:
           //ignore this message else pass it to base
           break;
        default:
           base.WndProc(ref m);
           break;
     }
  }

基本上,我只是忽略了 VM_ERASEBKGND 消息,在这种情况下它确实有效。 该应用程序是一个包含 PictureBox 的窗体。

现在,我想将它集成到另一个完全相同的项目中,一个 PictureBox 到一个 Form 中,但有更多的控件,例如 ScrollBar、Axis、GridPanel。

当我在另一个项目中以同样的方式覆盖 WndProc 方法时,即使它进入断点并且不处理它也不起作用 base.WndProc(ref m) 。但是,它似乎并不关心我没有处理消息,它仍然清除我的表单。

我的问题是:是否有可能像轴和滚动条这样的其他控件在离开屏幕时清除表单,即使我已经像上面的示例一样覆盖了 WndProc并忽略了 ERASEBKGND。

这是 windows 的一种非常奇怪的行为,因为它在一个应用程序中确实有效,但在另一个几乎相同的应用程序中却无效。

我解决这个问题的简单技巧,这不是你的情况下的最佳解决方案,但仍然有效,是覆盖你的表单的 WndProc 并捕获你的 VM_ERASEBKG。而不是传递给 base,而是返回你的交换链,它会重绘你的交换链。

GPU 和 CPU 来自 windows 32 个句柄在将 DirectX 与 winforms 一起使用时经常会出现不良行为。

Protected Overrides Sub WndProc(ByRef m As Message)
      Select Case m.Msg
         Case VM_ERASEBKGND
            swapchain.Present(1,PresentFlags.None)
            Exit Select
         Case Else
            MyBase.WndProc(m)
            Exit Select
      End Select
   End Sub