長時間批次運算、視訊播放、簡報模式等場景下,系統偵測不到使用者輸入會啟動螢幕保護程式,導致效能下降或畫面中斷。Windows 在啟動螢幕保護前,會向當前作用中應用程式發送 WM_SYSCOMMAND、wParam = SC_SCREENSAVE。攔截此消息並標記為「已處理」即可阻止啟動。
TApplication.OnMessageTApplication 擁有 OnMessage 事件,可攔截應用程式層級的所有佇列消息(PostMessage 投遞),但不包含 SendMessage 直接發送的消息。
typedef void __fastcall (__closure *TMessageEvent)(tagMSG &Msg, bool &Handled);
Msg:標準 MSG 結構,含 hwnd、message、wParam、lParam 等。Handled:設為 true 表示消息已處理,阻止後續分派;false 交由預設流程。class TForm1 : public TForm {
private:
void __fastcall CaptureMessage(tagMSG &Msg, bool &Handled);
public:
__fastcall TForm1(TComponent* Owner);
};
void __fastcall TForm1::CaptureMessage(tagMSG &Msg, bool &Handled)
{
if (Msg.message == WM_SYSCOMMAND && Msg.wParam == SC_SCREENSAVE) {
Handled = true; // 取消螢幕保護啟動
} else {
Handled = false; // 其餘消息走預設流程
}
}
FormCreate)void __fastcall TForm1::FormCreate(TObject *Sender)
{
Application->OnMessage = CaptureMessage;
}
SendMessage 直接送達視窗程序的消息(繞過佇列)。若需全攔截,請參考 Application->HookMainWindow 或重寫視窗程序。同樣機制可用於攔截 SC_MONITORPOWER(關閉螢幕)、SC_CLOSE(關閉視窗確認)等系統命令,實現更精細的電源管理與使用者體驗控制。