Accrocher une boucle de message Windows dans la fenêtre WPF ajoute une bordure blanche à l'intérieur

Je suis en train de créer une fenêtre WPF avec WindowStyle="None" (pour les boutons personnalisés et pas de titre) qui ne peuvent pas être redimensionnées. Réglage ResizeMode à NoResize supprime l'aéro-frontière, que je veux garder.

Je pourrais définir le min/max des propriétés de taille et être fait avec elle, sauf que:

  1. La redimensionner les curseurs sont encore visibles, et
  2. La fenêtre est affichée en réponse à une action de l'utilisateur et s'adapte à son contenu. Il affiche une image, de sorte que les changements de taille.

Donc, j'ai un système simple qui me fait 99% du chemin:

public class BorderedWindowNoResize : Window
{
    [DllImport( "DwmApi.dll" )]
    public static extern int DwmExtendFrameIntoClientArea(
        IntPtr hwnd,
        ref MARGINS pMarInset );

    [DllImport( "user32.dll", CharSet = CharSet.Auto )]
    public static extern IntPtr DefWindowProc(
        IntPtr hWnd,
        int msg,
        IntPtr wParam,
        IntPtr lParam );

    public BorderedWindowNoResize()
    {           
        Loaded += BorderedWindowNoResize_Loaded;
    }

    private void BorderedWindowNoResize_Loaded( object sender, RoutedEventArgs e )
    {           
        IntPtr mainWindowPtr = new WindowInteropHelper( this ).Handle;
        HwndSource mainWindowSrc = HwndSource.FromHwnd( mainWindowPtr );            
        mainWindowSrc.AddHook( WndProc );
    }

    private IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled )
    {           
        var htLocation = DefWindowProc( hwnd, msg, wParam, lParam ).ToInt32();

        if( msg == (uint)WM.NCHITTEST )
        {
            handled = true;
            switch( htLocation )
            {
                case (int)HitTestResult.HTBOTTOM:
                case (int)HitTestResult.HTBOTTOMLEFT:
                case (int)HitTestResult.HTBOTTOMRIGHT:
                case (int)HitTestResult.HTLEFT:
                case (int)HitTestResult.HTRIGHT:
                case (int)HitTestResult.HTTOP:
                case (int)HitTestResult.HTTOPLEFT:
                case (int)HitTestResult.HTTOPRIGHT:
                    htLocation = (int)HitTestResult.HTBORDER;
                    break;
            }               
        }

        return new IntPtr( htLocation );
    }
}

Fondamentalement;

  1. Remplacer la procédure de fenêtre.
  2. Appel à la procédure de fenêtre par défaut.
  3. Si le message c'est WM_NCHITTESTvérifiez la frontière résultats.
  4. Si c'est une frontière, le retour régulier HTBORDER.

Cela fonctionne aussi loin que de me permettre de garder l'aéro bordure de fenêtre et de cacher le curseur de redimensionnement(s), mais il ajoute un ~5 pixel blanc de la frontière à l'intérieur de ma fenêtre.

En fait, même si je retourne la procédure de windows par défaut suite au sommet de WndPrc et ne rien faire d'autre de la frontière est encore. J'ai besoin d'une couleur de fond différente sur ma fenêtre, de sorte que cela ne fonctionne pas pour moi.

Des idées? Merci à l'avance, comme toujours.

source d'informationauteur Ed S.