web-dev-qa-db-fra.com

Ombre portée sur un WinForm sans bordure

J'essaie de déposer une ombre autour de l'ensemble du formulaire, tout comme la première image, sauf que c'est un WPF, pas un WinForm. maintenant je veux déposer la même ombre sur un winform.

C'est ce que je veux ..

Windows Form Shadow

Pas ça ...

Windows Form Shadow

22
Sam Oyl

Dans WinForms, vous pouvez simplement remplacer la propriété CreateParams protégée du formulaire et ajouter la CS_DROPSHADOW drapeau pour les styles de classe. Par exemple:

public class ShadowedForm : Form {
    protected override CreateParams CreateParams {
        get {
            const int CS_DROPSHADOW = 0x20000;
            CreateParams cp = base.CreateParams;
            cp.ClassStyle |= CS_DROPSHADOW;
            return cp;
        }
    }

    // ... other code ...
}

Mais, quelques mises en garde…

  1. Cet indicateur ne fonctionne que sur les fenêtres de niveau supérieur. En langage Win32, cela signifie des fenêtres superposées et contextuelles. Il n'a aucun effet sur les fenêtres enfants (par exemple les contrôles). Je pensais me souvenir d'avoir entendu quelque part que cette limitation avait été supprimée de Windows 8, mais je ne trouve pas de lien le confirmant et je n'ai pas Windows 8 installé à des fins de test.

  2. Il est possible que l'utilisateur ait complètement désactivé cette fonctionnalité. Si c'est le cas, vous n'obtiendrez pas d'ombres portées, quelle que soit la façon dont vous les demandez. C'est par conception. Votre application ne doit pas essayer de remplacer cette demande. Vous pouvez déterminer si les ombres portées sont activées ou désactivées en P/en appelant la fonction SystemParametersInfo et en passant la SPI_GETDROPSHADOW drapeau.

  3. Le thème Aero ajoute également des ombres aux fenêtres de niveau supérieur. Cet effet est distinct et distinct de CS_DROPSHADOW, et fonctionne uniquement lorsque Aero est activé. Il n'y a aucun moyen de l'éteindre et de l'activer pour des fenêtres individuelles. De plus, puisque le thème Aero a été supprimé de Windows 8, il n'aura jamais ces ombres.

45
Cody Gray

Voici mon implémentation C #. C'est similaire à Al. Petro's, mais vous remarquerez que lorsque vous perdez votre concentration et que vous la regagnez, l'ombre se repeint.

J'ai également ajouté du code pour permettre le glissement de la souris.

public partial class Form1: Form
{
    [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
    private static extern IntPtr CreateRoundRectRgn
    (
        int nLeftRect, // x-coordinate of upper-left corner
        int nTopRect, // y-coordinate of upper-left corner
        int nRightRect, // x-coordinate of lower-right corner
        int nBottomRect, // y-coordinate of lower-right corner
        int nWidthEllipse, // height of ellipse
        int nHeightEllipse // width of ellipse
     );        

    [DllImport("dwmapi.dll")]
    public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);

    [DllImport("dwmapi.dll")]
    public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);

    [DllImport("dwmapi.dll")]
    public static extern int DwmIsCompositionEnabled(ref int pfEnabled);

    private bool m_aeroEnabled;                     // variables for box shadow
    private const int CS_DROPSHADOW = 0x00020000;
    private const int WM_NCPAINT = 0x0085;
    private const int WM_ACTIVATEAPP = 0x001C;

    public struct MARGINS                           // struct for box shadow
    {
        public int leftWidth;
        public int rightWidth;
        public int topHeight;
        public int bottomHeight;
    }

    private const int WM_NCHITTEST = 0x84;          // variables for dragging the form
    private const int HTCLIENT = 0x1;
    private const int HTCAPTION = 0x2;

    protected override CreateParams CreateParams
    {
        get
        {
            m_aeroEnabled = CheckAeroEnabled();

            CreateParams cp = base.CreateParams;
            if (!m_aeroEnabled)
                cp.ClassStyle |= CS_DROPSHADOW;

            return cp;
        }
    }

    private bool CheckAeroEnabled()
    {
        if (Environment.OSVersion.Version.Major >= 6)
        {
            int enabled = 0;
            DwmIsCompositionEnabled(ref enabled);
            return (enabled == 1) ? true : false;
        }
        return false;
    }

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_NCPAINT:                        // box shadow
                if (m_aeroEnabled)
                {
                    var v = 2;
                    DwmSetWindowAttribute(this.Handle, 2, ref v, 4);
                    MARGINS margins = new MARGINS()
                    {
                        bottomHeight = 1,
                        leftWidth = 1,
                        rightWidth = 1,
                        topHeight = 1
                    };
                    DwmExtendFrameIntoClientArea(this.Handle, ref margins);

                }
                break;
            default:
                break;
        }
        base.WndProc(ref m);

        if (m.Msg == WM_NCHITTEST && (int)m.Result == HTCLIENT)     // drag the form
            m.Result = (IntPtr)HTCAPTION;

    }

    public Form1()
    {
        m_aeroEnabled = false;

        this.FormBorderStyle = FormBorderStyle.None;

        InitializeComponent();
    }
}
20
Ryan Loggerythm

Humm , Juste après le code et vous obtiendrez Windows 7 Drop Shadow comme ceci >>> http://marcin.floryan.pl/wp-content/uploads/2010/08/WPF-Window- native-shadow.png

Imports System.Runtime.InteropServices

Public Class IMSS_SplashScreen
    Private aeroEnabled As Boolean
    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            CheckAeroEnabled()
            Dim cp As CreateParams = MyBase.CreateParams
            If Not aeroEnabled Then
                cp.ClassStyle = cp.ClassStyle Or NativeConstants.CS_DROPSHADOW
                Return cp
            Else
                Return cp
            End If
        End Get
    End Property
    Protected Overrides Sub WndProc(ByRef m As Message)
        Select Case m.Msg
            Case NativeConstants.WM_NCPAINT
                Dim val = 2
                If aeroEnabled Then
                    NativeMethods.DwmSetWindowAttribute(Handle, 2, val, 4)
                    Dim bla As New NativeStructs.MARGINS()
                    With bla
                        .bottomHeight = 1
                        .leftWidth = 1
                        .rightWidth = 1
                        .topHeight = 1
                    End With
                    NativeMethods.DwmExtendFrameIntoClientArea(Handle, bla)
                End If
                Exit Select
        End Select
        MyBase.WndProc(m)
    End Sub
    Private Sub CheckAeroEnabled()
        If Environment.OSVersion.Version.Major >= 6 Then
            Dim enabled As Integer = 0
            Dim response As Integer = NativeMethods.DwmIsCompositionEnabled(enabled)
            aeroEnabled = (enabled = 1)
        Else
            aeroEnabled = False
        End If
    End Sub
End Class
Public Class NativeStructs
    Public Structure MARGINS
        Public leftWidth As Integer
        Public rightWidth As Integer
        Public topHeight As Integer
        Public bottomHeight As Integer
    End Structure
End Class
Public Class NativeMethods
    <DllImport("dwmapi")> _
    Public Shared Function DwmExtendFrameIntoClientArea(ByVal hWnd As IntPtr, ByRef pMarInset As NativeStructs.MARGINS) As Integer
    End Function
    <DllImport("dwmapi")> _
    Friend Shared Function DwmSetWindowAttribute(ByVal hwnd As IntPtr, ByVal attr As Integer, ByRef attrValue As Integer, ByVal attrSize As Integer) As Integer
    End Function
    <DllImport("dwmapi.dll")> _
    Public Shared Function DwmIsCompositionEnabled(ByRef pfEnabled As Integer) As Integer
    End Function
End Class
Public Class NativeConstants
    Public Const CS_DROPSHADOW As Integer = &H20000
    Public Const WM_NCPAINT As Integer = &H85
End Class
9
Al.Pertro

Pour autant que je sache, il n'y a aucun moyen direct de le faire dans WinForms.

Au lieu de cela, vous pouvez suivre cette étape par étape:

1) Créez une image ayant l'ombre portée souhaitée à l'aide de photoshop ou de tout autre outil.
2) Utilisez cette image comme image d'arrière-plan de votre formulaire.
3) Définissez la propriété FormBorderStyle du formulaire sur Aucun.
4) Vous avez terminé!
5) Remarque: Veillez à enregistrer l'image au format approprié (tel que png) afin que l'effet d'ombre portée puisse fonctionner.

0
Amit Mittal

J'ai déjà répondu ici: Ombre portée sur Borderless Winform-No scintillement ou disparition

Voici ma réponse:

Veuillez essayer les étapes ci-dessous et revenir en arrière pour toute erreur:

Ajoutez le code ci-dessous à un nouveau fichier de code nommé DropShadow.cs;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Core
{
    public class DropShadow
    {
        #region Shadowing

        #region Fields

        private bool _isAeroEnabled = false;
        private bool _isDraggingEnabled = false;
        private const int WM_NCHITTEST = 0x84;
        private const int WS_MINIMIZEBOX = 0x20000;
        private const int HTCLIENT = 0x1;
        private const int HTCAPTION = 0x2;
        private const int CS_DBLCLKS = 0x8;
        private const int CS_DROPSHADOW = 0x00020000;
        private const int WM_NCPAINT = 0x0085;
        private const int WM_ACTIVATEAPP = 0x001C;

        #endregion

        #region Structures

        [EditorBrowsable(EditorBrowsableState.Never)]
        public struct MARGINS
        {
            public int leftWidth;
            public int rightWidth;
            public int topHeight;
            public int bottomHeight;
        }

        #endregion

        #region Methods

        #region Public

        [DllImport("dwmapi.dll")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);

        [DllImport("dwmapi.dll")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);

        [DllImport("dwmapi.dll")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public static extern int DwmIsCompositionEnabled(ref int pfEnabled);

        [EditorBrowsable(EditorBrowsableState.Never)]
        public static bool IsCompositionEnabled()
        {
            if (Environment.OSVersion.Version.Major < 6) return false;

            bool enabled;
            DwmIsCompositionEnabled(out enabled);

            return enabled;
        }

        #endregion

        #region Private

        [DllImport("dwmapi.dll")]
        private static extern int DwmIsCompositionEnabled(out bool enabled);

        [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
        private static extern IntPtr CreateRoundRectRgn
        (
            int nLeftRect,
            int nTopRect,
            int nRightRect,
            int nBottomRect,
            int nWidthEllipse,
            int nHeightEllipse
         );

        private bool CheckIfAeroIsEnabled()
        {
            if (Environment.OSVersion.Version.Major >= 6)
            {
                int enabled = 0;
                DwmIsCompositionEnabled(ref enabled);

                return (enabled == 1) ? true : false;
            }
            return false;
        }

        #endregion

        #region Overrides

        public void ApplyShadows(Form form)
        {
            var v = 2;

            DwmSetWindowAttribute(form.Handle, 2, ref v, 4);

            MARGINS margins = new MARGINS()
            {
                bottomHeight = 1,
                leftWidth = 0,
                rightWidth = 0,
                topHeight = 0
            };

            DwmExtendFrameIntoClientArea(form.Handle, ref margins);
        }

        #endregion

        #endregion

        #endregion
    }
}

Dans votre formulaire, ajoutez cette ligne sous InitializeComponent ();

(new Core.DropShadow()).ApplyShadows(this);
0
D J