阴影在一个无国界的WinForm(Drop Shadow On A Borderless WinFo

2019-09-02 14:13发布

我想串门整个形式的阴影就像第一张图片,除了这是一个WPF不是一个WinForm。 现在我想砸一个winform相同的阴影。

这是我want..¬

不this..¬

Answer 1:

在的WinForms,你可以重写形式的保护CreateParams属性和添加CS_DROPSHADOW标志的类样式。 例如:

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 ...
}

但是,需要注意几个问题...

  1. 此标志仅适用于顶级窗口。 在Win32中发言,这意味着重叠和弹出窗口。 它有子窗口(如控制)没有影响。 我想我记得听到的地方,这个限制已经从Windows 8中删除,但我无法找到一个链接,确认这一点,Windows 8的安装用于测试目的,我没有。

  2. 这可能是用户完全禁用此功能。 如果是这样,你就不会得到阴影,无论你怎么问他们。 这是由设计。 您的应用程序不应该试图和覆盖此请求。 您可以决定阴影是否已启用或P /禁用调用SystemParametersInfo函数并传递SPI_GETDROPSHADOW标志。

  3. Aero主题还增加了阴影顶级窗口。 这种效果是独立和独特CS_DROPSHADOW ,并启用Aero的时候起作用。 有没有办法将其关闭,并就各个窗口。 此外,由于Aero主题已经从Windows 8的删除,它永远不会有这些阴影。



Answer 2:

这里是我的C#实现。 它类似于Al.Pertro的,但你会发现,当你失去焦点,并重新获得焦点,阴影重新绘制本身。

我还添加代码,让鼠标拖动。

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();
    }
}


Answer 3:

赫姆,,,刚刚过去的代码,你会得到Windows 7的阴影像这样>>> 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


Answer 4:

据我所知,有在的WinForms这样做的直接方式。

相反,你可以按照这个一步一步:

1)创建用photoshop或其他任何工具具有所需阴影的图像。
2)使用这个图像作为形式的背景图像。
3)设置窗体为无的FormBorderStyle属性。
4)你完成了!
5)注:请务必保存适当格式的图像(如PNG),使阴影效果可以工作。



文章来源: Drop Shadow On A Borderless WinForm