Sleep 會阻塞執行緒,導致介面凍結、無法處理訊息 (重繪、按鈕點擊等)。在需要短暫延遲但必須保持 UI 回應的場合,需自訂延遲函式並呼叫 Application.ProcessMessages。
procedure Delay(MilliSeconds: Integer);
var
StartTick: DWORD;
begin
StartTick := GetTickCount;
repeat
Application.ProcessMessages; // 處理排隊訊息,保持 UI 回應
until (GetTickCount - StartTick) >= Cardinal(MilliSeconds);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := '步驟 1';
Delay(1000); // 延遲 1 秒,介面仍可移動、重繪
Label1.Caption := '步驟 2';
Delay(500);
Label1.Caption := '完成';
end;
GetTickCount 回傳系統啟動至今毫秒數 (DWORD),差值運算自動處理溢位 (無符號減法)。Application.ProcessMessages 會處理所有待處理訊息,包含重繪、滑鼠、鍵盤、定時器等。Button1.Enabled := False) 或使用旗標防重入。TTimer 或執行緒,避免阻塞主執行緒過久。QueryPerformanceCounter 替代 GetTickCount (約 15ms 解析度)。procedure SafeDelay(MilliSeconds: Integer; var ReentrancyGuard: Boolean);
begin
if ReentrancyGuard then Exit;
ReentrancyGuard := True;
try
Delay(MilliSeconds);
finally
ReentrancyGuard := False;
end;
end;