Search code examples
c#winformspaint

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


I have a windows form application that draws image and geometry form in front of it. I have a problem that occurs when I drag the windows form off-screen and bring it back on-screen, makes the part that went off-screen all cleared.

I read that this might occurs because of windows message sending to my application the VM_ERASEBKGND and clear the part that went off-screen. (Am I right ? )

So first, I have created a test application that only displays an image and I overrides the WndProc method that does work in that case, here how it is implemented :

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;
     }
  }

Basically, I'm am just ignoring VM_ERASEBKGND message, and it does work in that case. The application is a Form that contains a PictureBox.

Now, I wanted to integrate this to another project that is quite the same, a PictureBox into a Form, but has some more Control such has ScrollBar , Axis, GridPanel.

When overwriting the WndProc method the same way I did in another project, it doesn't work even though it goes into the break point and does not process base.WndProc(ref m). However, it seems to doesn't care that I am not processing the message, it still does clear my Form.

My question is : is it possible that other control like axis and scrollbar makes the form cleared when moving off-screen even though I've overwritten WndProc like in the example above and ignored ERASEBKGND.

This is a really weird behavior from windows since it does work in one application, but not in another which is almost the same.


Solution

  • My easy trick to resolve this problem, which is not the best solutions in your case, but still works, is to override WndProc of your form and catch your VM_ERASEBKG. And instead of passing to base, Present back your swapchain which redraws your swapchain.

    GPU and CPU from windows 32 handles often gives bad behavior when using DirectX with 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