O que faz com que o Windows seja interrompido neste aplicativo WPF Ribbon

Tivemos alguns problemas com um aplicativo de área de trabalho bastante grande e complexo, em que o uso do Microsoft Ribbon para WPF (ou uma combinação de coisas conectadas a ele) faz com que o computador seja interrompido.

O código resumido abaixo parece ativar uma situação de interrupção do Windows em vários computadores. Alguns computadores experimentarão esse travamento sempre, alguns nunca irão experimentá-lo. O travamento irá, em algum computador, travar toda a sessão (incluindo num lock e caps lock), mas em outros, o mouse ainda irá se mover (num lock ainda fora do negócio). Quando o computador não responde, parece que coisas como logon remoto e compartilhamento de rede ainda funcionam, mas não é possível encerrar a sessão do console.

Em resumo, o que parece ser a causa raiz do comportamento é a combinação de algumas coisas:

Faixa de Opções Microsoft para WPFAplicativo do Windows Forms que hospeda o controle do WPF em um ElementHostO uso de formulários do Windows com buffer duplo (pelo uso de CreateParams)O uso de renderização de software na faixa de opções do WPF

Mais tarde, resolvemos esse problema usandoWS_EX_COMPOSITED apenas em alguns formulários selecionados, mas gostaria muito de descobrir a causa raiz desse problema.

Eu ainda tenho que descobrir uma maneira direta de reproduzir o jeito, mas esse aplicativo mínimo parece fazer o trabalho, pelo menos em algumas máquinas, fazendo um pouco de maximizar / restaurar e passar o mouse sobre o botão da faixa de opções.

O código a seguir é compilado como x86 .NET 4.0, contra oFaixa de opções do Microsoft WPF Biblioteca do .NET 4.0.

using System;
using System.Windows.Forms;
using Microsoft.Windows.Controls.Ribbon;
using System.Windows.Interop;
using System.Windows.Forms.Integration;

namespace WindowsRibbonHang
{
    public class Form1 : Form
    {
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED
                return cp;
            }
        }

        public Form1()
        {
            Ribbon ribbon = new Ribbon();

            RibbonTab tab = new RibbonTab { Header = "FooTab" };
            ribbon.Items.Add(tab);

            RibbonSplitButton button = new RibbonSplitButton { Label = "FooButton" };
            tab.Items.Add(button);

            ElementHost elementHost = new ElementHost
            {
                Dock = DockStyle.Fill,
                Child = ribbon,
            };

            Controls.Add(elementHost);
            Dock = DockStyle.Fill;

            ribbon.Loaded += (sender, args) => {
                HwndSource hwndSource = System.Windows.PresentationSource.FromVisual(ribbon) as HwndSource;
                HwndTarget hwndTarget = hwndSource.CompositionTarget;
                hwndTarget.RenderMode = RenderMode.SoftwareOnly;
            };
        }
    }

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

questionAnswers(2)

yourAnswerToTheQuestion