首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

C++Builder/Delphi 主視窗最小化無動畫原因分析與解決方案

     編輯:VC 教學

問題根源

VCL 應用程式的主視窗實為 TApplication 物件(0x0 大小,位於螢幕中心),工作列按鈕對應的也是這個隱形視窗。真正的表單 TForm1 不具 WS_EX_APPWINDOW 樣式,故不在工作列顯示。最小化時,VCL 為避免 0x0 視窗動畫難看,呼叫 SystemParametersInfo(SPI_SETANIMATION) 關閉動畫,並直接隱藏 TForm1,導致整體無動畫效果。

VCL 原始碼關鍵片段 (Forms.pas)

procedure TApplication.Minimize;
begin
    if not IsIconic(FHandle) then begin
        NormalizeTopMosts;
        SetActiveWindow(FHandle);
        ShowWinNoAnimate(FHandle, SW_MINIMIZE); // 強制無動畫
        if Assigned(FOnMinimize) then FOnMinimize(Self);
    end;
end;

procedure ShowWinNoAnimate(Handle: HWnd; CmdShow: Integer);
var Animation: Boolean;
begin
    Animation := GetAnimation;
    if Animation then SetAnimation(False); // 暫停系統動畫
    ShowWindow(Handle, CmdShow);
    if Animation then SetAnimation(True);  // 恢復系統動畫
end;

procedure SetAnimation(Value: Boolean);
var Info: TAnimationInfo;
begin
    Info.cbSize := SizeOf(TAnimationInfo);
    BOOL(Info.iMinAnimate) := Value;
    SystemParametersInfo(SPI_SETANIMATION, SizeOf(Info), @Info, 0);
end;

解決方案:讓主表單成為真正的應用程式視窗

  1. 複製 Forms.pas 到專案目錄,從專案原始碼移除預設 Forms 單元,改加入複製的 Forms.pas。
  2. 修改專案原始碼 (.dpr):
program Project1;
uses Windows, Unit1 in 'Unit1.pas' {Form1}, Forms in 'Forms.pas';
{$R *.RES}
begin
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    SetWindowLong(Form1.Handle, GWL_EXSTYLE,
        GetWindowLong(Form1.Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);
    Form1.Show;
    ShowWindow(Application.Handle, SW_HIDE); // 隱藏 TApplication 視窗
    Application.Run;
end.
  1. 修改 Forms.pas 中 TCustomForm.WMSysCommand,註解掉最小化時呼叫 Application.Minimize 的邏輯,直接呼叫 inherited。
procedure TCustomForm.WMSysCommand(var Message: TWMSysCommand);
begin
    { if (Message.CmdType and $FFF0 = SC_MINIMIZE) and
       (Application.MainForm = Self) then
        Application.Minimize
    else } // 註解掉原邏輯
    inherited;
end;

完成後主表單將具備正常最小化/還原動畫。但此法有副作用(如工作列按鈕行為變化),需視專案需求權衡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved