Delphi 應用需實現「無操作超時自動退出」功能。核心思路:**應用級消息鉤子**攔截 `WM_MOUSEMOVE`、`WM_KEYDOWN` 重置計時器,`TTimer` 定期檢查超時並調用 `Close`。本文提供完整單元代碼、關鍵點解析、多表單/MDI 擴展建議。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
procedure AppMessageHandler(var Msg: TMsg; var Handled: Boolean);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
// 應用級消息處理器:捕獲鼠標移動、鍵盤按下
procedure TForm1.AppMessageHandler(var Msg: TMsg; var Handled: Boolean);
begin
if (Msg.message = WM_MOUSEMOVE) or (Msg.message = WM_KEYDOWN) then
Timer1.Tag := 0; // 重置空閒計數
end;
// 定時器事件:每秒檢查
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Tag := Timer1.Tag + 1; // Tag 用作秒計數器
if Timer1.Tag >= 30 then // 超過 30 秒
Close; // 關閉主窗體 → 應用退出
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Close; // 手動關閉按鈕
end;
end.
Application.OnMessage := Form1.AppMessageHandler;
這使主窗體能攔截**全應用範圍**的鼠標/鍵盤消息,不僅限於當前表單。
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
// 關鍵:註冊應用消息鉤子
Application.OnMessage := Form1.AppMessageHandler;
Application.Run;
end.
uses Winapi.Windows;
function GetIdleTime: DWORD;
var
li: TLastInputInfo;
begin
li.cbSize := SizeOf(TLastInputInfo);
if GetLastInputInfo(li) then
Result := GetTickCount - li.dwTime
else
Result := 0;
end;
// 定時器中調用
if GetIdleTime >= 30000 then Close;
優點:系統級、跨進程、不依賴消息鉤子、更準確 (包含所有輸入設備)。缺點:需 Vista+,無法區分「本應用」與「其它應用」的操作。