Wiki Link: [discussion:5422]
Flickering when restore or maximize window 

Oct 5 2012 at 8:22 AM
I have tried this solution and I have seen annoying flickering when I maximze or restore the window without native windows chrome means only with custom wpf chrom. So I've extend the messagr handler methods with few traces.
So I see that _HandleNCCalcSize is called about 23 times when windows is beeing maximized or restored following by 23 calls of _HandleWindowPosChanged.
Each _HandleWindowPosChanged call sets window regions which causes window redraw each time. Also the method _HandleNCCalcSize returns WVR.REDRAW which also causes unnecessary redraw. I feel this is some kind of recursion - setting regions in WinPosChanged causes NCCalcSize which causes again WindposChanged.

So I tried to improve a little bit an came up with few simple lines of code, which works very well for my windows and I don't see any flickering any more. _HandleNCCalcSize and _HandleWindowPosChanged are called only once at each window maximize or minimize:


private WINDOWPOS _previousWP;

private IntPtr _HandleWindowPosChanged(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled)
{
// http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx
// The WM_WINDOWPOSCHANGED message is sent at the end of the window
// state change process. It sort of combines the other state change
// notifications, WMMOVE, WMSIZE, and WM_SHOWWINDOW. But it doesn't
// suffer from the same limitations as WM_SHOWWINDOW, so you can
// reliably use it to react to the window being shown or hidden.

_UpdateSystemMenu(null);

if (!_isGlassEnabled)
{
Assert.IsNotDefault(lParam);
var wp = (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS));

if(!wp.Equals(_previousWP))
{
_previousWP = wp;
_SetRoundingRegion(wp);
}

if (wp.Equals(previousWP) && wp.EqualsFlags(previousWP))
{
handled = true;
return IntPtr.Zero;
}

_previousWP = wp;

Debug.WriteLine(@"HandleWindowPosChanged : *************** WindowState:" + this._window.WindowState + @" WindowPos: " + wp + @"******************");

}

// Still want to pass this to DefWndProc
handled = false;
return IntPtr.Zero;
}

In NCCalSize I also return 0 instead of WVR_REDRAW each time:

private IntPtr _HandleNCCalcSize(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled)
{
// lParam is an in, out that can be either a RECT* (wParam == FALSE) or an NCCALCSIZE_PARAMS*.
// Since the first field of NCCALCSIZE_PARAMS is a RECT and is the only field we care about
// we can unconditionally treat it as a RECT.

// Since we always want the client size to equal the window size, we can unconditionally handle it
// without having to modify the parameters.
Debug.WriteLine(@"HandleNCCalcSize : *************** WindowState:" + this._window.WindowState + @"******************");

if((int)wParam==1)
{
handled = true;
return IntPtr.Zero;
}

handled = true;
return new IntPtr((int)WVR.REDRAW);
}

My be it would help some one.

Regards,Alex

Apr 2 at 2:27 PM
hi,

this solution works for me too, but i'm interessted on this method

wp.EqualsFlags(previousWP)

thx


Updating...
Page view tracker