Vb.net 在WinForm上放置阴影会扭曲接口

Vb.net 在WinForm上放置阴影会扭曲接口,vb.net,winforms,dropshadow,Vb.net,Winforms,Dropshadow,我正在使用以下代码在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 <Dl

我正在使用以下代码在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
_
私有共享函数DwmSetWindowAttribute(hwnd作为IntPtr,attr作为Integer,ByRef attrValue作为Integer,attrSize作为Integer)作为Integer
端函数
_
私有共享函数dwmextendframeintoclienterea(hWnd作为IntPtr,ByRef pMarInset作为边距)作为整数
端函数
私有函数CreateDropShadow()作为布尔值
尝试
Dim val为整数=2
Dim ret1作为整数=DwmSetWindowAttribute(Me.Handle,2,val,4)
如果ret1=0,则
将m调整为新边距(0,0,0,0)
Dim ret2作为整数=DwmExtendFrameIntoClientArea(Me.Handle,m)
返回ret2=0
其他的
返回错误
如果结束
特例
'可能找不到dwmapi.dll(不兼容的操作系统)
返回错误
结束尝试
端函数
已创建受保护的重写子句柄(e作为事件参数)
CreateDropShadow()
MyBase.OnHandleCreated(e)
端接头
上面代码的结果在我的无边界winform上创建了一个很好的阴影效果,但它会导致UI扭曲。表单上的所有控件和标签显示不正确,文本不可读

我是不是遗漏了什么?我不想使用CreateParams使用传统的阴影效果,它看起来太“方形”,不能提供很好的阴影效果

以下是无阴影和有阴影的屏幕截图:

谢谢

  Dim m As New Margins(0, 0, 0, 0)
这里可以看到一个细微的错误,看起来很像您在使用System.Drawing.Printing.Margins。但这不是与Windows的边距类型兼容的类型。这是一个结构,不是一个类

所以这完全错了,Windows读取的是无意义的内容,而不是(0,0,0,0)。并将框架扩展到整个客户端区域。这会对任何使用GDI绘制的控件造成严重破坏,它是一个24bpp的绘制api,将alpha保留为0,因此任何应该为黑色的控件都将变为透明

通过声明适当的页边距结构来解决此问题:

Structure MARGINS
    Public Left, Right, Top, Bottom As Integer
End Structure

我想知道为什么这在一开始对你有效。我尝试调用
dwmextendframeintoclienterea
函数,所有方面的maring值都为0,结果是我没有得到任何阴影效果(Windows7SP1,x86)。然而,如果我称之为每边边距1,我会得到所需的空气动力下降阴影。剩下要做的唯一一件事就是用表单的背景色对这样创建的框架区域进行过度渲染。否则我没有注意到任何奇怪的行为。你确定你有一个无边界表单吗?当你的意思是使用无边界表单时,
FormBorderStyle
属性设置为
None
,那么是的,我确定。是的,这就是我所说的。再次看到我的问题,我现在添加了截图,使用的代码与我的问题相同。是的,这就是问题所在,截图清楚地显示了问题所在。在我的测试中,我添加了正确的结构,所以我无法复制它。是的,这修复了它。正如@Andreasader所说,将边距保持在零并不会产生阴影,所以我将所有边的边距都改为1。现在就像一个符咒。真是一个看不见的错误。谢谢你,汉斯。