【问题标题】:Disable animation effects for windows with C#使用 C# 禁用窗口的动画效果
【发布时间】:2016-07-15 12:14:53
【问题描述】:

我正在尝试禁用窗口中的“淡入淡出”动画,每当您打开或最大化/最小化窗口时就会发生这种动画。

当然也可以手动取消勾选最小化和最大化时动画窗口

我正在尝试通过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 仍会继续为我调整大小的任何窗口设置动画。

我将它编译为 AnyCPU,在 Windows 10 上以管理员身份运行。

对于@cody gray,这是代码(将 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);
     }

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

【问题讨论】:

  • 您可能需要注销并重新登录才能看到它...
  • @AustinFrench 我会试一试...稍后回来:)
  • @AustinFrench 仍然没有任何改变 :) 我尝试禁用其他属性 - 例如禁用投影msdn.microsoft.com/en-us/library/windows/desktop/… 并且它确实有效.. :(
  • 它为帧设置动画,不知道“褪色”可能是什么样子。使用 DwmSetWindowAttribute() 如this snippet 所示。
  • @Slashy:谢谢,现在 +1,因为它使问题变得完整。

标签: c# .net windows winapi animation


【解决方案1】:

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

使用起来有点复杂,因为pvParam参数必须指向一个ANIMATIONINFO结构。这是相当没有意义的,因为结构只有一个有意义的成员,但这就是 API 的设计方式。据推测,几年前的意图是让这成为 所有 的 shell 动画效果的切换,但无论出于何种原因,这最终都没有发生,并且单独的 SPI_* 值被用于他们每个人。不幸的是,你选错了。是a long list

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 function 一起使用,以在隐藏或显示窗口时禁用转换。

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

Hans Passant 将您链接到 one of his answers,其中包含如何从 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));
}

【讨论】:

  • “除非您正在制作桌面自定义实用程序” - 或测试自动化实用程序,它可以捕获屏幕截图并需要可重现的矩形窗口,而不是在窗口看起来像梯形的动画中间捕获它们。
  • @Cody Gray 它的意图是为屏幕共享项目捕获矩形窗口——TeamvViewer 等软件用来减少网络流量的技巧之一 :) 。所以我需要使用第一个代码。当我尝试用它编译我的问题时,它几乎没有简单的问题。如果您能再次提供帮助,我将不胜感激:)
  • @Cody Gray 没关系。感谢您的精彩回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
  • 2016-12-25
  • 2013-09-17
  • 1970-01-01
相关资源
最近更新 更多