在 WinForm 上添加阴影会扭曲界面。

4
我正在使用以下代码为我的WinForms创建Windows7风格的下拉阴影效果:
<DllImport("dwmapi.dll", PreserveSig:=True)> _
Private Shared Function DwmSetWindowAttribute(hwnd As IntPtr, attr As Integer, ByRef attrValue As Integer, attrSize As Integer) As Integer
End Function

<DllImport("dwmapi.dll")> _
Private Shared Function DwmExtendFrameIntoClientArea(hWnd As IntPtr, ByRef pMarInset As Margins) As Integer
End Function

Private Function CreateDropShadow() As Boolean
    Try
        Dim val As Integer = 2
        Dim ret1 As Integer = DwmSetWindowAttribute(Me.Handle, 2, val, 4)

        If ret1 = 0 Then
            Dim m As New Margins(0, 0, 0, 0)
            Dim ret2 As Integer = DwmExtendFrameIntoClientArea(Me.Handle, m)
            Return ret2 = 0
        Else
            Return False
        End If
    Catch ex As Exception
        ' Probably dwmapi.dll not found (incompatible OS)
        Return False
    End Try
End Function

Protected Overrides Sub OnHandleCreated(e As EventArgs)
    CreateDropShadow()
    MyBase.OnHandleCreated(e)
End Sub

上面代码的结果在我的无边框 winform 上创建了一个漂亮的阴影效果,但它会导致 UI 失真。我的窗体上所有的控件和标签都显示不正常,文本不可读。
我错过了什么吗?我不想使用传统的 CreateParams 方式创建阴影效果,因为它看起来太“盒状”了,不能产生好的阴影效果。
下面是没有阴影和有阴影的截图: Form without drop shadow Form with drop shadow 谢谢。

我想知道为什么这对你来说首先能够工作。我尝试调用DwmExtendFrameIntoClientArea函数并将所有边缘的间距都设置为0,结果是我没有获得任何投影效果(Windows 7 SP1,x86)。然而,如果我为每个边缘调用它时使用间距1,则可以获得所需的aero投影。唯一剩下要做的就是用窗体的背景颜色覆盖已创建的框架区域。否则,我没有注意到任何奇怪的行为。 - Andreas Adler
你确定你有一个无边框的窗体吗? - Faraz Azhar
当您指的是无边框表单,即 FormBorderStyle 属性设置为 None,那么是的,我确定。 - Andreas Adler
是的,这就是我所说的。请再看一下我的问题,我现在已经添加了截图,使用的是与我的问题相同的代码。 - Faraz Azhar
1个回答

4
  Dim m As New Margins(0, 0, 0, 0)

这里有一个微小的错误,看起来很像你正在使用System.Drawing.Printing.Margins。但这个类型与Windows的MARGINS类型不兼容。MARGINS是一个结构体,而不是类。
因此,这样做完全错误,Windows会读取无意义的内容,而不是(0, 0, 0, 0)。并将框架扩展到整个客户端区域。这会对使用GDI绘制的任何控件造成混乱,它是一个24bpp的绘图API,将alpha值保留为0,因此任何应该是黑色的东西都变成了透明的。
通过声明一个正确的MARGINS结构来修复这个问题:
Structure MARGINS
    Public Left, Right, Top, Bottom As Integer
End Structure

是的,那肯定是问题所在,截图清楚地显示了它。为了进行测试,我添加了正确的结构,因此无法再现它。 - Andreas Adler
是的,问题已经解决了。就像@AndreasAdler所说,将MARGINS保持为零并没有产生阴影,所以我将其改为所有边缘都为1。现在完美地工作了。真是一个难以察觉的错误。谢谢Hans。 - Faraz Azhar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接