使用C#禁用Windows的animation效果

我试图禁用窗口中的“褪色”animation,每当你打开或最大化/最小化窗口时发生。

当然,这可以通过在最小化和最大化时取消animation窗口的checkbox来手动完成

我试图通过SystemParametersInfo这是我的电话:

[DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool SystemParametersInfo(uint uiAction, uint uiParam, bool pvParam,uint fWinIni); private static UInt32 SPIF_SENDCHANGE = 0x02; private static UInt32 SPI_SETUIEFFECTS = 0x103F; public static void Main() { bool res= SystemParametersInfo(SPI_SETUIEFFECTS, 0, false, SPIF_SENDCHANGE); } 

result值总是为True ,所以我知道函数调用成功。

但我看不到任何结果… Windows仍然保持animation我调整任何窗口。

我编译为AnyCPU,作为pipe理员在Windows 10上运行。

对于@cody灰色这是代码(将ref关键字添加到ai参数,并将Marshal.Sizeof(ai)转换为uint)。

  [StructLayout(LayoutKind.Sequential)] public struct ANIMATIONINFO { public uint cbSize; public int iMinAnimate; }; [DllImport("user32", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref ANIMATIONINFO pvParam, uint fWinIni); public static uint SPIF_SENDCHANGE = 0x02; public static uint SPI_SETANIMATION = 0x0049; public static void Main() { ANIMATIONINFO ai=new ANIMATIONINFO(); ai.cbSize = (uint)Marshal.SizeOf(ai); ai.iMinAnimate = 0; // turn all animation off SystemParametersInfo(SPI_SETANIMATION, 0, ref ai, SPIF_SENDCHANGE); } 

最后一个问题 – 如果我想回到原来的状态 – 这意味着我想再次激活animation,为了做到这一点,应该改变什么参数?

当您调用SystemParametersInfo时,您没有设置正确的选项。 控制最小化/最大化动画效果(在UI中标记为“当最小化和最大化时动画化窗口” )的参数是SPI_SETANIMATION

使用它有点复杂,因为pvParam参数必须指向一个ANIMATIONINFO结构。 这是毫无意义的,因为结构只有一个有意义的成员,但这是API的设计方式。 据推测,多年以前的意图是为所有的壳动画效果切换,但不管什么原因,这并没有最终发生,并分别使用SPI_*值。 你不幸选错了。 这是一个长长的清单 。

C#中的示例代码:

 [StructLayout(LayoutKind.Sequential)] public struct ANIMATIONINFO { public uint cbSize; public int iMinAnimate; }; [DllImport("user32", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref ANIMATIONINFO pvParam, uint fWinIni); public static uint SPIF_SENDCHANGE = 0x02; public static uint SPI_SETANIMATION = 0x0049; public static void Main() { ANIMATIONINFO ai; ai.cbSize = Marshal.SizeOf(ai); ai.iMinAnimate = 0; // turn all animation off SystemParametersInfo(SPI_SETANIMATION, 0, ai, SPIF_SENDCHANGE); } 

请注意,这是一个全局设置 ,影响所有应用程序。 应用程序需要切换此开关是非常罕见的,除非您正在制作桌面自定义实用程序。 因此,您将需要管理权限来更改此设置。


还有DWMWA_TRANSITIONS_FORCEDISABLED标志,您可以使用DwmSetWindowAttribute函数禁用窗口隐藏或显示时的转换。

这样做的好处是它是一个本地解决方案 – 只能更改一个窗口的设置。 但是,如果您不使用DWM(在旧版本的Windows上),它将不会执行任何操作,并且最小化/最大化转换仍然可见。 我还没有全面地测试这两个选项之间的相互作用。

Hans Passant将你与他的答案之一联系起来, 其中包含了一个如何从C#中调用DwmSetWindowAttribute的嵌入式示例。 这里是相关的位:

 const int DWMWA_TRANSITIONS_FORCEDISABLED = 3; [DllImport("dwmapi", PreserveSig = true))] static extern int DwmSetWindowAttribute(IntPtr hWnd, int attr, ref int value, int attrLen); 
 // in the form's constructor: // (Note: in addition to checking the OS version for DWM support, you should also check // that DWM composition is enabled---or at least gracefully handle the function's // failure when it is not. Instead of S_OK, it will return DWM_E_COMPOSITIONDISABLED.) if (Environment.OSVersion.Version.Major >= 6) { int value = 1; // TRUE to disable DwmSetWindowAttribute(this.Handle, DWMWA_TRANSITIONS_FORCEDISABLED, ref value, Marshal.SizeOf(value)); }