具有最小化动画的.NET / WinForms自定义表单边框

时间:2014-05-06 21:33:57

标签: c++ winforms animation minimize

我知道我之前已经看过这个问题,但答案是不确定的或不满意的(从我能看到的),所以我想在这里提出我的情况。我正在创建一个具有自定义表单边框的程序(即表单边框样式=无,并带有我们自己的控件)。该程序没有最小化/关闭动画,而只是快照。

这是一个.NET表单(使用C ++ / CLR) - 我能做些什么吗?我已经看到其他程序执行此操作(例如,Photoshop CS6 / CC具有恢复动画,但不是最小化动画)。

我是否可以通过覆盖CreateParams来应用属性/样式?我是#ha; hacky"方法,但改变形式边框样式的方式,让用户暂时看到边框不是一个可行的选择。

提前致谢。

1 个答案:

答案 0 :(得分:0)

我最终使用了自定义动画,并认为我会分享相关代码。以下WndProc捕获的覆盖最小化/恢复(包括单击/双击任务栏)。请注意,设置WindowState不会触发此操作 - 您必须手动将带有WM_SYSCOMMAND的SC_MINIMIZE lpa发送到窗口(或手动设置动画)。整个动画代码,包括计时器在下面。

//Define a variable so it knows what animation is happening
short fade_mode = 0; //0 is fade in, 1 is minimize, 2 is close
short close_on_close = FALSE; //a variable to tell the close handler to re-animate or not - this allows this->Close(); to trigger the animation but avoids a loop.

//The WndProc
        protected: virtual void WndProc(System::Windows::Forms::Message% msg) override {
            switch (msg.Msg) {
            case WM_SYSCOMMAND:
                switch (msg.WParam.ToInt32()) {
                case SC_MINIMIZE:
                    msg.Result = IntPtr::Zero;
                    fade_mode = 1;                      
                    fadetimer->Start();
                    return;
                    break;                  
                }
                break;                                  
            case WM_ACTIVATE: {                 
                if (HIWORD(msg.WParam.ToInt32()) == 0) { //because non-zero wpa here means the form is minimized
                    this->WindowState = FormWindowState::Normal;                        
                    fade_mode = 0;
                    fadetimer->Start();
                    msg.Result = IntPtr::Zero;
                    return;
                }
            }
            }

            Form::WndProc(msg);

        }


//The button event handlers
private: System::Void btn_close_Click(System::Object^  sender, System::EventArgs^  e) {
    this->Close();
}
private: System::Void btn_minimize_Click(System::Object^  sender, System::EventArgs^  e) {      
    SendMessage(HWND(this->Handle.ToPointer()), WM_SYSCOMMAND, SC_MINIMIZE, NULL);      
}

//The event animation code itself (set to a tick of 10ms) and the form closing handler:
private: System::Void fadetimer_Tick(System::Object^  sender, System::EventArgs^  e) {
    if (this->IsDisposed == true) { //In the event that the form opened/closed quickly and has not stopped properly, clean up to avoid crashes.
        fadetimer->Stop();
        return;
    }
    switch (fade_mode) {        
    case 0: //fading in
        if (this->Opacity < 1)
            this->Opacity += 0.2;
        else {
            fade_mode = -1;
            fadetimer->Stop();
        }
        break;
    case 1: //minimizing
        if (this->Opacity > 0)
            this->Opacity -= 0.2;
        else {
            fade_mode = -1;
            fadetimer->Stop();
            this->WindowState = Windows::Forms::FormWindowState::Minimized;
        }
        break;
    case 2: //closing
        if (this->Opacity > 0)
            this->Opacity -= 0.2;
        else {
            fade_mode = -1;
            fadetimer->Stop();
            close_on_close = TRUE;
            this->Close();
        }
        break;
    }
}
private: System::Void loginform_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e) {
    if (close_on_close == FALSE) {
        e->Cancel = true;           
        fade_mode = 2;
        fadetimer->Start();
    }
}

确保默认情况下将表单的不透明度设置为0% - 它应该在首次创建/显示时自动淡入(我的确如此,我无法记住,如果我&#39 ;做了其他事情,使其如此)。