c# - 使用 C# 禁用窗口的动画效果

标签 c# .net windows winapi animation

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

当然也可以通过取消选中最小化和最大化时动画窗口的复选框来手动完成

我正在尝试通过 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);
     }

最后一个问题 - 如果我想回到原来的状态 - 这意味着我想再次激事件画,应该更改什么参数才能做到这一点?

最佳答案

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

使用起来有点复杂,因为pvParam参数必须指向一个ANIMATIONINFO结构。这是毫无意义的,因为该结构只有一个有意义的成员,但这就是 API 的设计方式。据推测,几年前的意图是将其作为 所有 外壳动画效果的切换,但无论出于何种原因,这并没有最终发生,并且将 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));
}

关于c# - 使用 C# 禁用窗口的动画效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38395882/

相关文章:

c# - 当我使用多个项目替代一个项目中多个目录的 C# 时,是否存在性能损失

.net - 是否有适用于 WPF 的(好的/免费的)VirtualizingWrapPanel?

linux - 使用putty连接windows和linux机器

类似于eternity的C++对象持久化库

c# - 设计简单的代码优先电影数据库(多对多)EF

c# - 将函数作为参数传递给 Action

c# - 我如何找到字符串 c# 中的最后一个数字?

c++ - 在 VC++2010 环境之外运行时程序立即崩溃

c# - 将 onmouseout 更改为另一个元素的颜色

.net - 卸载 CodeRush 和 ReSharper - Intellisense 不起作用