VCL 應用程式的主視窗實為 TApplication 物件(0x0 大小,位於螢幕中心),工作列按鈕對應的也是這個隱形視窗。真正的表單 TForm1 不具 WS_EX_APPWINDOW 樣式,故不在工作列顯示。最小化時,VCL 為避免 0x0 視窗動畫難看,呼叫 SystemParametersInfo(SPI_SETANIMATION) 關閉動畫,並直接隱藏 TForm1,導致整體無動畫效果。
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;
Forms.pas 到專案目錄,從專案原始碼移除預設 Forms 單元,改加入複製的 Forms.pas。.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.
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;
完成後主表單將具備正常最小化/還原動畫。但此法有副作用(如工作列按鈕行為變化),需視專案需求權衡。