ForegroundIdleProc 配合 WH_FOREGROUNDIDLE 鉤子類型,在前台線程訊息佇列空閒時被系統周期性呼叫。類似 WM_ENTERIDLE 但更底層,可用於背景低優先級任務、自動儲存、垃圾回收等。
function ForegroundIdleProc(
nCode: Integer; // 鉤子代碼
wParam: WPARAM; // 保留,通常 0
lParam: LPARAM // 保留,通常 0
): LRESULT; stdcall;
HC_ACTION (0) 表示前台線程進入閒置狀態,可執行任務;負值傳遞給 CallNextHookEx。GetMessage/PeekMessage 即將等待新訊息前。| 屬性 | 系統級 (dwThreadId=0) | 線程級 (dwThreadId=目標線程) |
|---|---|---|
| 回調位置 | DLL | EXE 可行 |
| 監控範圍 | 所有前台線程 | 單一線程 |
| 適用場景 | 系統級工具 (螢幕保護、備份代理) | 應用內部閒置任務 |
SetTimer / WM_TIMER:固定間隔,可靠Application.OnIdle (VCL) / TIdleTimer:框架級閒置處理WaitableTimer + 背景線程:精確、不阻塞 UIunit IdleHookUnit;
interface
uses Windows, Classes;
var hIdleHook: HHOOK = 0;
IdleCounter: Integer = 0;
function ForegroundIdleProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
if nCode = HC_ACTION then
begin
Inc(IdleCounter);
if IdleCounter >= 100 then // 約 100 次空閒週期
begin
IdleCounter := 0;
// 執行自動儲存等低優先級任務
// 注意:此處不可做耗時操作,建議 PostMessage 通知主線程
end;
end;
Result := CallNextHookEx(hIdleHook, nCode, wParam, lParam);
end;
procedure InstallIdleHook(ThreadId: DWORD);
begin
if hIdleHook = 0 then
hIdleHook := SetWindowsHookEx(WH_FOREGROUNDIDLE, @ForegroundIdleProc, HInstance, ThreadId);
end;
procedure UninstallIdleHook;
begin
if hIdleHook <> 0 then
begin
UnhookWindowsHookEx(hIdleHook);
hIdleHook := 0;
end;
end;
implementation
end.
WH_FOREGROUNDIDLE 是較冷門的鉤子類型,現代開發極少直接使用。理解其存在有助於維護舊代碼,新專案請優先選用 Timer、OnIdle、背景線程等更可控的方案。