Hello,
thanks for information. I don't think that we can live with the extra border. But I found another workaround that seems to be much better than forcing software rendering. I found it here:
http://archive.msdn.microsoft.com/WPFShell
I downloaded the source and added a WebBrowser control to the example project. When using the "Gradient Chrome" style that is similar to the Actipro tool Windows the webbrowser starts to flicker as expected. But when "Glassy Chrome" had been selected at least once the flickering is gone. Because of this I searched the sources for a reason and found this in WindowChromeWorker.cs:333:
// There was a regression in DWM in Windows 7 with regard to handling WM_NCCALCSIZE to effect custom chrome.
// When windows with glass are maximized on a multimonitor setup the glass frame tends to turn black.
// Also when windows are resized they tend to flicker black, sometimes staying that way until resized again.
//
// This appears to be a bug in DWM related to device bitmap optimizations. At least on RTM Win7 we can
// evoke a legacy code path that bypasses the bug by calling an esoteric DWM function. This doesn't affect
// the system, just the application.
// WPF also tends to call this function anyways during animations, so we're just forcing the issue
// consistently and a bit earlier.
What the code basically does is call DwmGetCompositionTimingInfo:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa969514(v=vs.85).aspx
So I added a handler for the Loaded event of the ToolWindow that hosts the WebBrowser control that looks like this:
[StructLayout(LayoutKind.Sequential)]
internal struct UNSIGNED_RATIO
{
public uint uiNumerator;
public uint uiDenominator;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct DWM_TIMING_INFO
{
public int cbSize;
public UNSIGNED_RATIO rateRefresh;
public ulong qpcRefreshPeriod;
public UNSIGNED_RATIO rateCompose;
public ulong qpcVBlank;
public ulong cRefresh;
public uint cDXRefresh;
public ulong qpcCompose;
public ulong cFrame;
public uint cDXPresent;
public ulong cRefreshFrame;
public ulong cFrameSubmitted;
public uint cDXPresentSubmitted;
public ulong cFrameConfirmed;
public uint cDXPresentConfirmed;
public ulong cRefreshConfirmed;
public uint cDXRefreshConfirmed;
public ulong cFramesLate;
public uint cFramesOutstanding;
public ulong cFrameDisplayed;
public ulong qpcFrameDisplayed;
public ulong cRefreshFrameDisplayed;
public ulong cFrameComplete;
public ulong qpcFrameComplete;
public ulong cFramePending;
public ulong qpcFramePending;
public ulong cFramesDisplayed;
public ulong cFramesComplete;
public ulong cFramesPending;
public ulong cFramesAvailable;
public ulong cFramesDropped;
public ulong cFramesMissed;
public ulong cRefreshNextDisplayed;
public ulong cRefreshNextPresented;
public ulong cRefreshesDisplayed;
public ulong cRefreshesPresented;
public ulong cRefreshStarted;
public ulong cPixelsReceived;
public ulong cPixelsDrawn;
public ulong cBuffersEmpty;
}
[DllImport("dwmapi.dll", EntryPoint = "DwmGetCompositionTimingInfo")]
private static extern uint DwmGetCompositionTimingInfo(IntPtr hwnd, ref DWM_TIMING_INFO pTimingInfo);
private void BrowserWindow_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
var obj = sender as DependencyObject;
if (null!=obj && Environment.OSVersion.Version.Major==6 && Environment.OSVersion.Version.MajorRevision==1)
{
Window wnd = Window.GetWindow(obj);
if (wnd is ActiproSoftware.Windows.Controls.Docking.Primitives.RaftingWindow)
{
WindowInteropHelper helper = new WindowInteropHelper(wnd);
var dti = new DWM_TIMING_INFO { cbSize = Marshal.SizeOf(typeof(DWM_TIMING_INFO)) };
uint hresult = DwmGetCompositionTimingInfo(helper.Handle, ref dti);
}
}
}
This removed the flickering completely for me. May be RaftingWindow could do this internally in some way? Otherwise it might just be helpful to people with the same problem.
Regards,
Markus