HWND API:如何在调用ShowWindow(...)时禁用窗口动画

时间:2016-06-07 04:44:41

标签: c# winapi hwnd

我想知道在调用HWnd ShowWindow()方法时如何抑制动画。这是我的代码:

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);

public enum ShowWindowCommands
{
    HIDE = 0,
    SHOWNORMAL = 1,
    SHOWMINIMIZED = 2,
    MAXIMIZE = 3,
    SHOWNOACTIVATE = 4,
    SHOW = 5,
    MINIMIZE = 6,
    SHOWMINNOACTIVE = 7,
    SHOWNA = 8,
    RESTORE = 9,
    SHOWDEFAULT = 10,
    FORCEMINIMIZE = 11
}

public static void MinimizeWindow(IntPtr hWnd)
{
    ShowWindow(hWnd, ShowWindowCommands.MINIMIZE);
}

问题是,动画执行,并且在动画结束之前方法不会返回。

我尝试使用DwmSetWindowAttribute()方法:

[DllImport("dwmapi.dll", PreserveSig = true)]
static extern int DwmSetWindowAttribute(IntPtr hWnd, uint attr, ref int attrValue, int size);

const uint DWM_TransitionsForceDisabled = 3;

public static void SetEnabled(IntPtr hWnd, bool enabled)
{
    int attrVal = enabled ? 0 : 1;
    DwmSetWindowAttribute(hWnd, DWM_TransitionsForceDisabled, ref attrVal, 4);
}

但是这些动画没有受到抑制。 我的操作系统是Windows 7,32位。

2 个答案:

答案 0 :(得分:0)

https://devblogs.microsoft.com/oldnewthing/20121003-00/?p=6423


BOOL ani = TRUE;
DwmSetWindowAttribute(m_top, DWMWA_TRANSITIONS_FORCEDISABLED, &ani, sizeof(ani));

答案 1 :(得分:-1)

不是最佳选择,但您可以尝试调用SystemParametersInfo()指定SPI_GETANIMATION以获取窗口动画的当前设置,如果已启用,则在显示窗口之前使用SPI_SETANIMATION禁用它们,然后恢复以前的设置。例如:

[StructLayout(LayoutKind.Sequential)]
public struct ANIMATIONINFO
{
  uint cbSize;
  int iMinAnimate;
}

[DllImport("User32.dll", SetLastError=true)]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref ANIMATIONINFO pvParam, uint fWinIni);

const uint SPI_GETANIMATION = 72;
const uint SPI_SETANIMATION = 73;

public static void MinimizeWindow(IntPtr hWnd)
{
    ANIMATIONINFO anim;
    anim.cbSize = Marshal.SizeOf(anim);
    anim.iMinAnimate = 0;
    SystemParametersInfo(SPI_GETANIMATION, 0, anim, 0);

    if (anim.iMinAnimate != 0)
    {
        anim.iMinAnimate = 0;
        SystemParametersInfo(SPI_SETANIMATION, 0, anim, 0);

        ShowWindow(hWnd, ShowWindowCommands.MINIMIZE);

        anim.iMinAnimate = 1;
        SystemParametersInfo(SPI_SETANIMATION, 0, anim, 0);
    }
    else
        ShowWindow(hWnd, ShowWindowCommands.MINIMIZE);
}