1

我想禁用窗口的表单淡入效果。我想我找到了正确的功能

<DllImport("dwmapi.dll", PreserveSig:=True)> _
Private Shared Function DwmSetWindowAttribute(ByVal hwnd As IntPtr, ByVal attr As Integer, ByRef attrValue As Integer, ByVal attrSize As Integer) As Integer
End Function

标志应该是

DWMWA_TRANSITIONS_FORCEDISABLED

但我不知道如何从 VB.NET 调用它。这是我到目前为止所拥有的:

Imports System.Runtime.InteropServices

Public Class Form1

Public Enum DWMWINDOWATTRIBUTE
    DWMWA_ALLOW_NCPAINT = 4
    DWMWA_CAPTION_BUTTON_BOUNDS = 5
    DWMWA_FLIP3D_POLICY = 8
    DWMWA_FORCE_ICONIC_REPRESENTATION = 7
    DWMWA_LAST = 9
    DWMWA_NCRENDERING_ENABLED = 1
    DWMWA_NCRENDERING_POLICY = 2
    DWMWA_NONCLIENT_RTL_LAYOUT = 6
    DWMWA_TRANSITIONS_FORCEDISABLED = 3
End Enum

<DllImport("dwmapi.dll", PreserveSig:=True)> _
Private Shared Function DwmSetWindowAttribute(ByVal hwnd As IntPtr, ByVal attr As Integer, ByRef attrValue As Integer, ByVal attrSize As Integer) As Integer
End Function

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Environment.OSVersion.Version.Major >= 6 Then
        DwmSetWindowAttribute Me.Handle, 'here I don't know how to go on...
    End If
End Sub
End Class

非常感谢你的帮助!

4

3 回答 3

2

文档DWMWA_TRANSITIONS_FORCEDISABLED内容如下:

与 DwmSetWindowAttribute 一起使用。启用或强制禁用 DWM 转换。pvAttribute 参数指向值 TRUE 以禁用转换或 FALSE 以启用转换。

TRUEFALSE声明为:

#define FALSE 0
#define TRUE  1

所以你需要传递参数1attrValue

Windows 原生使用的布尔类型是BOOL. 这是这样声明的:

typedef int BOOL;

既然sizeof(int)4attrSize你需要通过的是4

于 2012-12-22T11:13:13.387 回答
1

由于属性值参数类型,该函数很尴尬。它使用 void*,这是接受不同大小值的 C 函数的典型特征。这实际上是您可以在 VB.NET 中轻松处理的事情,您可以使用不同类型的参数编写同一函数的不同重载。然后编译器会根据您传递的参数自动确定要调用哪一个。

让我们关注您要更改的特定属性,它是一个 BOOL 值。因此,编写一个采用布尔值的函数的重载,它会自动封送为 BOOL ,而无需您提供帮助:

<DllImport("dwmapi.dll")> _
Private Shared Function DwmSetWindowAttribute(ByVal hwnd As IntPtr, _
            ByVal attr As Integer, ByRef attrValue As Boolean, _
            ByVal attrSize As Integer) As Integer
End Function

让我们简化枚举,您只需要其中一个:

Private Const DWMWA_TRANSITIONS_FORCEDISABLED As Integer = 3

然后你需要改变你调用这个函数的地方,一个窗口可以被创建多次但Load事件只运行一次。您需要在创建窗口后立即调用它。添加错误处理,以便您可以诊断运行时问题:

Protected Overrides Sub OnHandleCreated(ByVal e As System.EventArgs)
    MyBase.OnHandleCreated(e)
    If Environment.OSVersion.Version.Major >= 6 Then
        Dim hr = DwmSetWindowAttribute(Me.Handle, _
                    DWMWA_TRANSITIONS_FORCEDISABLED, True, 4)
        If hr < 0 Then Marshal.ThrowExceptionForHR(hr)
    End If
End Sub

当我测试它时效果很好。

于 2012-12-22T12:26:25.043 回答
1

对我有用的是

    If Environment.OSVersion.Version.Major >= 6 Then
        DwmSetWindowAttribute(Me.Handle, DWMWINDOWATTRIBUTE.DWMWA_TRANSITIONS_FORCEDISABLED, 1, 4)
    End If

但这只是一个猜测。我不确定“1”是否代表 YES,也不确定长度 4 在所有情况下是否正确。确认这一点会很棒。谢谢!

于 2012-12-22T09:45:38.313 回答