3

I'm trying to disable the "fading" animation in windows which happens whenever you open or maximize/minimize a window.

Of course it can be done manually by unticking the checkbox of animate windows when minimizing and maximizing

I'm trying to do this through the SystemParametersInfo This is my call:

    [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 value is always True , so I know the function was successfully called.

But I can't see any results...Windows still keep animating any window I resize.

I compile this as AnyCPU, running as adminstrator on Windows 10.

for @cody gray this is the code (added the ref keyword to the ai paramater and converted the Marshal.Sizeof(ai) to `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);
     }

One last question-if i would like to get back to the original state-which means i want to activate the aniamtions again,what parameter should be changed in order to do this?

Slashy
  • 1,841
  • 3
  • 23
  • 42
  • You might have to log out and back in for it to be visible... – Austin T French Jul 15 '16 at 12:16
  • @AustinFrench i'll try it... coming back in a second :) – Slashy Jul 15 '16 at 12:17
  • @AustinFrench still nothing changed :) i tried to disable other properties-such as disabling the drop shadow https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947(v=vs.85).aspx#spi_setdropshadow and it did work.. :( – Slashy Jul 15 '16 at 12:24
  • It animates the frame, no real idea what "fading" might look like. Use DwmSetWindowAttribute() as shown in [this snippet](http://stackoverflow.com/a/4503371/17034). – Hans Passant Jul 15 '16 at 12:33
  • @Slashy: thanks, +1 now, since it makes the question complete. – Thomas Weller Jul 15 '16 at 13:26
  • To get back to the original state, you need to use `SPI_GETANIMATION` to fill in the `ANIMATIONINFO` struct *first*, save the value of `ANIMATIONINFO.iMinAnimate`, call using `SPI_SETANIMATION` to change the value as you want it, and then restore it afterwards with a *second* call using `SPI_SETANIMATION`. Hopefully that made sense. – Cody Gray - on strike Jul 15 '16 at 13:54

1 Answers1

3

You are not setting the right option when you call SystemParametersInfo. The one that controls the minimize/maximize animation effect (labeled in the UI as "Animate windows when minimizing and maximizing") is SPI_SETANIMATION.

Using it is a bit more complicated, because the pvParam parameter must point to an ANIMATIONINFO structure. It is rather pointless, because the struct only has one meaningful member, but that's the way the API was designed. Presumably, the intent years ago was for this to be a toggle for all of the shell animation effects, but for whatever reason, that didn't end up happening, and separate SPI_* values were used for each of them. You unfortunately picked the wrong one. It is a long list.

Sample code in 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);
}

Note that this is a global setting, affecting all applications. It is exceedingly rare that an application would ever need to toggle this switch, unless you were making a desktop customization utility. As such, you will require administrative privileges to change this setting.


There is also the DWMWA_TRANSITIONS_FORCEDISABLED flag that you can use with the DwmSetWindowAttribute function to disable transitions when a window is hidden or shown.

The advantage of this is that it is a local solution—you can change the setting only for a single window. But it won't do anything if you are not using DWM (on older versions of Windows), and the minimize/maximize transitions may still be visible. I haven't comprehensively tested the interaction between these two options.

Hans Passant linked you to one of his answers that contains an embedded example of how to call DwmSetWindowAttribute from C#. Here are the relevant bits:

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));
}
Community
  • 1
  • 1
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • 1
    "unless you were making a desktop customization utility" - or a test automation utility that captures screenshots and wants reproducible, rectangular shaped windows instead of capturing them in the middle of an animation where the window looks trapezoid. – Thomas Weller Jul 15 '16 at 13:22
  • @Cody Gray it's intetion is to capture rectangular shaped windows for a screen sharing project-one of the tricks that softwares like TeamvViewer use in order to reduce the network traffic :) . so i'll need to use the first code. There are few simple problems with it when i try to compile-edited my question with it. i'll appreciate if you can help again :) – Slashy Jul 15 '16 at 13:43
  • @Cody Gray nevermind . Thanks for your amazing answer. – Slashy Jul 15 '16 at 13:49