. net / winforms自定义窗体边界与最小化动画



我知道我以前见过这个问题,但答案一直不确定或不令人满意(从我所看到的),所以我想在这里提出我的情况。我正在创建一个程序,有一个自定义表单边界(即表单边界样式= None与我们自己的控制围绕它)。该程序没有最小化/关闭动画,而只是快照。

这是一个。net形式(使用c++/CLR) -我能做些什么吗?我看到过其他程序这样做(例如,Photoshop CS6/CC有还原动画,但没有最小化动画)。

是否有一个属性/样式我可以通过重写CreateParams应用?我喜欢"hack"的方法,但是改变表单的边框样式,让用户暂时看到边框,在这里不是一个可行的选择。

我最终使用了一个自定义动画,并认为我应该分享相关代码。下面重写的windowproc捕获最小化/恢复(包括从点击/双击任务栏)。注意,设置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% -它应该自动淡入当它第一次创建/显示(我的,我不记得如果我做了什么使它这样)。

最新更新