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

C# HWND API:如何在调用ShowWindow(…)时禁用窗口动画,c#,winapi,hwnd,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,

我想知道在调用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);
}
问题是,动画将执行,并且该方法在动画完成之前不会返回

我尝试使用以下方法:

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

不是最佳选项,但您可以尝试调用specifying 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, Marshal.SizeOf(anim), anim, 0);

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

        ShowWindow(hWnd, ShowWindowCommands.MINIMIZE);

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

这不是最佳选项,但您可以尝试调用specifying 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, Marshal.SizeOf(anim), anim, 0);

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

        ShowWindow(hWnd, ShowWindowCommands.MINIMIZE);

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

检查DwmSetWindowAttribute的返回值,看看它是否失败,如果失败,原因是什么。@Jonathan Potter返回值为零,即操作成功。查看答案,看起来您错误地传递了数据指针。当我将方法签名更改为使用IntPtr时,它返回代码0x800703e6对内存位置的无效访问。我使用的签名应该可以,因为它是我问题中链接中使用的签名。发布的代码片段是正确的。查找一个简单的错误,如调用SetEnabled太晚,或颠倒其enabled参数的含义,或使用错误的窗口句柄。检查DwmSetWindowAttribute的返回值是否失败,如果失败,原因是什么。@Jonathan Potter返回值为零,即operation Successful查看的答案,看起来您传递的数据指针不正确。当我将方法签名更改为使用IntPtr时,它将返回代码0x800703e6“对内存位置的无效访问”。我使用的签名应该可以,因为它是我问题中链接中使用的签名。发布的代码片段是正确的。寻找一个简单的错误,比如调用SetEnabled太晚,或者颠倒了其enabled参数的含义,或者使用了错误的窗口句柄。在旧的NewThing博客上,通常称为使用全局设置来解决局部问题,通常奇怪的是,即使我使用这个全局解决方案,动画仍然显示:@RemyLebeau-我不反对这个答案,但它对我也不起作用。唯一对我有效的解决方案是这个:但显然,我需要以编程方式完成它。我开始认为这可能是我的环境VirtualBox的一个问题vm@JonathanPotter事实上,在他编辑答案之前,我就已经熟悉了SystemParametersInfo的签名。我刚刚为我的操作系统安装了一个service pack,SystemParametersInfo方法现在正在工作,但是DwmSetWindowAttribute仍然不起作用。@AhmedOsama显然对SPI_SETANIMATION也是如此。在旧的New Thing博客上,通常指的是使用全局设置来解决局部问题,奇怪的是,即使我使用这个全局解决方案,动画仍然显示:@RemyLebeau-我不反对这个答案,但它对我也不起作用。唯一对我有效的解决方案是这个:但显然,我需要以编程方式完成它。我开始认为这可能是我的环境VirtualBox的一个问题vm@JonathanPotter事实上,在他编辑答案之前,我就已经熟悉了SystemParametersInfo的签名。我刚刚为我的操作系统安装了一个service pack,SystemParametersInfo方法现在正在工作,但是DwmSetWindowAttribute仍然不工作。@AhmedOsama显然对SPI_SETANIMATION也是一样的。

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