提问者:小点点

在Form_Load处使用AnimateWindow()


我有一个无边框的窗体,我使用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参数如何)。

有什么想法吗?


共1个答案

匿名用户

这是很难正确地做到的,有大量的代码涉及,是非常棘手的推理通过。 在WinForms中,Visible属性是一个非常重要的问题,它由Application类为启动窗体和Show()方法设置,当您创建自己的启动窗体时。 在典型的。NET方式中,本机窗口的创建是懒惰的,当球开始滚动时,会发生很多很多的事情。

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

您可以尝试以下代码,将其粘贴到窗体类中:

    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子表单上尝试,不太可能有好的结果。