none
Flickering in the custom form while resizing from top and left side

    Question

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

    I have overridden 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 approaches to reduce this 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


    Friday, February 9, 2018 2:48 PM

All replies

  • Hi Mohanram,

    Try to add this in WndProc function:

        if (m.Msg == 0x0014) // Banned clear the background message
            return;

    So it will be:

            protected override void WndProc(ref Message m)
            {
                if (m.Msg == 0x0014) // Banned clear the background message
                    return;
                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;
                }
            }

    Regards,

    Frankie


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, February 12, 2018 1:37 AM
    Moderator
  • Hi Frankie,

    I have tried this code.

    This makes the client area of the form as in the below image when I resize the form.

    What should I do now? whether I need to process any other window messages to resolve this. Please provide your valuable suggestions

    Regards,

    Mohanram

    Monday, February 12, 2018 5:00 AM
  • Hi Mohanram,

    That might because the background is being painted every time.

    Try this instead:

            private const int WM_ERASEBKGND = 20;
            [PermissionSet(SecurityAction.Demand, Unrestricted = true)]
            protected override void WndProc(ref Message m)
            {
                switch (m.Msg)
                {
                    case WM_ERASEBKGND:
                        m.Result = IntPtr.Zero;
                        break;
                    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;
                }
            }

    Regards,

    Frankie


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, February 12, 2018 8:30 AM
    Moderator
  • Hi Frankie,

    I have tried this code instead of the first one. This too makes the form same as the above image while resizing. 

    Is there any mistake in processing the WM_WINDOWPOSCHANGED window message?

    Regards,

    Mohanram

    Monday, February 12, 2018 8:47 AM
  • Hi Mohanram,

    The cause of the flicker is because there is the background brush with the windows message when you override it, I'm not the expert for windows message, it is related to c++, if you have some problem about windows message, I suggest you ask your question at C++ forum for help.

    Regards,

    Frankie


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, February 14, 2018 2:38 AM
    Moderator