Использование AnimateWindow() в Form_Load

У меня есть форма без полей, и я использую метод 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 ответ

Решение

Это довольно сложно сделать правильно, потому что задействовано огромное количество кода, который очень сложно обдумать. Свойство Visible, устанавливаемое классом Application для формы запуска и метода Show() при создании собственного приложения, очень важно в Winforms. Создание собственного окна лениво в типичной манере.NET, много-много чего происходит, когда мяч катится.

Вызов AnimateWindow() должен быть введен в промежуток времени между вызовом метода Show() и Winforms получает возможность вызвать PinWindow(). Это последний вызов, который разрушает эффект анимации, когда вы пробуете его в 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, она вряд ли придет к концу.

Другие вопросы по тегам