2

我有一个无边框的表单,我使用 AnimateWindow() 方法来创建用于打开、关闭等我的表单的动画。我使用这段代码:

[Flags]
enum AnimateWindowFlags
{
    AW_HOR_POSITIVE = 0x0000000
    AW_HOR_NEGATIVE = 0x00000002,
    AW_VER_POSITIVE = 0x00000004,
    AW_VER_NEGATIVE = 0x00000008,
    AW_CENTER = 0x00000010,
    AW_HIDE = 0x00010000,
    AW_ACTIVATE = 0x00020000,
    AW_SLIDE = 0x00040000,
    AW_BLEND = 0x00080000
}

[DllImport("user32.dll")]
static  extern bool AnimateWindow(IntPtr hWnd, int time, AnimateWindowFlags flags);

在关闭表单时,此代码似乎有效:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    AnimateWindow(this.Handle, 100, AnimateWindowFlags.AW_BLEND | AnimateWindowFlags.AW_HIDE);
}

但是,当使用此代码打开表单时:

private void Form1_Load(object sender, EventArgs e)
{
    AnimateWindow(this.Handle, 100, AnimateWindowFlags.AW_BLEND);
}

似乎什么也没有发生。在做了一些猜测和测试之后,我发现使用 AnimateWindow() 方法使表单淡出是可行的,但是使用它使表单淡入并没有做任何事情(不管time参数如何)。

有任何想法吗?

4

1 回答 1

4

这很难正确完成,涉及大量代码,很难推理。Visible 属性,由 Application 类为启动窗体和创建自己的 Show() 方法设置,在 Winforms 中非常重要。本机窗口创建在典型的 .NET 方式中是惰性的,当球滚动时会发生很多事情。

AnimateWindow() 调用必须在调用 Show() 方法和 Winforms 有机会调用 ShowWindow() 之间注入。当您在 OnLoad() 中尝试时,正是后一个调用破坏了动画效果,事件触发得太晚了。

您可以尝试此代码,将其粘贴到您的 Form 类中:

    protected override void SetVisibleCore(bool value) {
        if (!this.IsHandleCreated) {
            NativeMethods.AnimateWindow(this.Handle, 100, AnimateWindowFlags.AW_BLEND);
        }
        base.SetVisibleCore(value);
    }

    protected override void OnShown(EventArgs e) {
        this.BringToFront();
        base.OnShown(e);
    }

但我不能保证它会在所有可能的情况下工作,并且没有进行广泛的测试。不得不调用 BringToFront() 已经是一个令人不快的黑客行为。不要在 MDI 子窗体上尝试,不太可能有好的结果。

于 2015-07-22T17:56:45.243 回答