Starting with Windows Vista, if you register a reason line for WM_QUERYENDSESSION OS, or if your application has a top-level window, the OS will wait indefinitely for your program to return with WM_QUERYENDSESSION when the lock applications screen is displayed - or until the user decides, of course finish the program.
Below is an example code simulating 45 seconds of sleep using Sleep . In the first five seconds of waiting, the operating system waits patiently, only then displays a full-screen interface. The only way to immediately display the screen is to immediately return false from WM_QUERYENDSESSION . But in this case, you cannot resume the shutdown.
For more information about disabling the OS for Vista and later, see the documentation .
type TForm1 = class(TForm) .. protected procedure WMQueryEndSession(var Message: TWMQueryEndSession); message WM_QUERYENDSESSION; .. ... function ShutdownBlockReasonCreate(hWnd: HWND; Reason: LPCWSTR): Bool; stdcall; external user32; function ShutdownBlockReasonDestroy(hWnd: HWND): Bool; stdcall; external user32; procedure TForm1.WMQueryEndSession(var Message: TWMQueryEndSession); const ENDSESSION_CRITICAL = $40000000; begin Message.Result := LRESULT(True); if ((Message.Unused and ENDSESSION_CRITICAL) = 0) then begin ShutdownBlockReasonCreate(Handle, 'please wait while muting...'); Sleep(45000); // do your work here ShutdownBlockReasonDestroy(Handle); end; end;
source share