1

I have derived a class from System.Windows.Forms.Form class to create a custom form.

I have override the method WndProc(ref m) and process WM_NCPAINT window message to draw the caption bar with my own customization.

I have provided the basic version of my implementation below.

protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WindowMessages.WM_NCPAINT: // TO draw the title bar text and buttons
                    On_Wm_NcPaint(ref m);
                    break;
                case WindowMessages.WM_NCCALCSIZE: //To define the client area size of the form.
                    On_Wm_NcCalcSize(ref m);
                    break;
           case WindowMessages.WM_WINDOWPOSCHANGED:
                    On_Wm_WindowPosChanged(ref m);
                    break;
           case WindowMessages.WM_NCLBUTTONUP: //For handling close,minimize and maximize operations.
                    On_Wm_NcLButtonUp(ref m);
                    break;
        default:
                    base.WndProc(ref m);
                    break;
         }
      }

    private void On_Wm_WindowPosChanged(ref Message m)
        {
            NativeMethods.WINDOWPOS wpos = (NativeMethods.WINDOWPOS)m.GetLParam(typeof(NativeMethods.WINDOWPOS));
            if ((wpos.flags & WindowMessages.SWP_NOSIZE) == 0)
            {

                var rect = new NativeMethods.RECT();
                NativeMethods.GetWindowRect(this.Handle, ref rect);
                var region = NativeMethods.CreateRectRgn(0, 0, rect.Width, rect.Height);
                if (region != IntPtr.Zero)
                    NativeMethods.SetWindowRgn(this.Handle, region, true);
                Invalidate();
                                return;
              }

            base.WndProc(ref m);
         }   

This works properly for me.

The problem with this is, the form flickers when resizing from the top and left side of the form.

It seems that the below things happens when I increase the form size by resizing from the left side.

  1. First the form is repositioning to the left side.
  2. Then the width of the form is increasing in the right.

This happens little slowly, so that it looks like flickering.

Note : Flickering occurs in the form. Not in the controls added to the form.

I have tried the below ways to resolve flickering.

SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer
                | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);


this.DoubleBuffered = true; 

 protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }

These approaches doesn't give any result.

This flickering doesn't occurs in the base form (System.Windows.Forms.Form)

This may occurs due to the incorrect handling of the WindowMessage WM_WINDOWPOSCHANGED.

Please share your ideas to get rid of this flickering and to get a smooth resizing.

Thanks in advance

  • Please show the **relevant** parts of your code so we can see a) what you are doing and b) how you have tried to fix the problem. – stuartd Feb 08 '18 at 11:42
  • Resizing right and bottom is more winapi efficient (winforms using it), because only small rectangle is invalidated. If you resize left and top, then the complete form has to redraw. Did you try to [enable double-buffering](https://learn.microsoft.com/en-us/dotnet/framework/winforms/advanced/how-to-reduce-graphics-flicker-with-double-buffering-for-forms-and-controls) or [similar](https://stackoverflow.com/q/302614/1997232)? – Sinatr Feb 08 '18 at 12:23
  • Microsoft suggests another approach to enable double buffering [here](https://learn.microsoft.com/en-us/dotnet/framework/winforms/advanced/how-to-reduce-graphics-flicker-with-double-buffering-for-forms-and-controls). Did you try that? – Alex Seleznyov Feb 08 '18 at 12:45
  • Yes. I have tried both the approaches – Mohanram Anbukkarasu Feb 08 '18 at 13:02
  • The Form class, like all classes derived from ScrollableControl, uses an optimized form of painting. It only redraws the part of the window that is revealed by a resize. Inevitably that is only optimal if the bottom or right edge of the window is dragged. If you do any painting with the form's OnPaint() or Paint event then you must use ResizeRedraw = true in the constructor, failure to do so can cause very awkward painting artifacts, tend to resemble a smear. Delays are now consistent and you no longer have to worry about what edge you drag. – Hans Passant Feb 08 '18 at 13:29
  • Are the controls inside the Form positioned via `Dock` or are they `Anchor`ed? I Noticed that `Dock` causes more flickering in some situations. – Otterprinz Feb 08 '18 at 21:04
  • I have updated the question by adding the basic version of my implementation. Check this now and provide your suggestions – Mohanram Anbukkarasu Feb 12 '18 at 09:57

0 Answers0