简体   繁体   中英

Using AnimateWindow() at Form_Load

I have a borderless form and I use the AnimateWindow() method to create animations for opening, closing, etc my Form. I use this code:

[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);

When it comes to closing the form, this code seems to work:

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

However, when opening the form with this code:

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

Nothing seems to happen. After doing some guesses and tests I figured that using the AnimateWindow() method to make the form fade out works, but using it to make the form fade in doesn't do anything (regardless of the time parameter).

Any ideas?

This is pretty difficult to do correctly, there is an enormous amount of code involved that is very tricky to reason through. The Visible property, set by the Application class for the startup form and the Show() method when you create your own is a very big deal in Winforms. The native window creation is lazy in typical .NET fashion, lots and lots of stuff happens when the ball gets rolling.

The AnimateWindow() call must be injected in between the time the Show() method is called and Winforms gets a chance to pinvoke ShowWindow(). It is the latter call that ruins the animation effect when you try it in OnLoad(), the event fires too late.

You can try this code, paste it into your Form class:

    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);
    }

But I cannot promise it will work in all possible cases and have not tested it extensively. Having to call BringToFront() was already an unpleasant hack. Don't try it on an MDI child form, not likely to come to a good end.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM