How to pause Windows shutdown

后端 未结 2 1737
广开言路
广开言路 2021-01-19 16:04

I need to mute/un-mute the sound card at startup and shutdown.

I have found some code to do the work, but often Windows slams through the shutdown and the sound neve

相关标签:
2条回答
  • 2021-01-19 16:29

    You need to handle the WM_QUERYENDSESSION messsage. It's sent to each application before Windows starts the shutdown process. Do what you need quickly, because failure to respond rapidly enough causes the behavior you're observing in FireFox, which is usually a sign of a badly designed app (and the user may terminate it before you get a chance to finish).

    interface
    
    ...
    
    type
      TForm1 = class(TForm)
        procedure WMQueryEndSession(var Msg: TWMQueryEndSession);
          message WM_QUERYENDSESSION;
      end;
    
    implementation
    
    procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession);
    begin
      // Do what you need to do (quickly!) before closing
      Msg.Result := True; 
    end;
    

    (Just as an aside: The enabling/disabling of sounds is a per-user setting, and you should have a very good need for interfering with the user's choice. If I were you, I'd make sure my uninstaller was well-tested, because any app that interfered with my sound preferences this way would be removed from my system very quickly.)

    0 讨论(0)
  • 2021-01-19 16:41

    Since Windows Vista, if you register a shutdown reason string with the OS or if your application has a top level window, the OS will wait indefinitely for your program to return from WM_QUERYENDSESSION while displaying the blocking applications screen - or until the user chooses to forcefully end the program of course.

    The below sample code simulates a 45 seconds wait with Sleep. In the first five seconds of the wait the OS waits patiently, only then it displays the full screen UI. The only way to show the screen immediately is to immediately return false from WM_QUERYENDSESSION. But in this case you won't be able to resume shutdown.

    For details on shutdown behavior of the OS for Vista and later, see 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;
    
    0 讨论(0)
提交回复
热议问题