如何暂停Windows关机

时间:2013-08-20 23:30:23

标签: delphi delphi-5 system-shutdown

我需要在启动和关闭时将声卡静音/取消静音。

我已经找到了一些代码来完成这项工作,但是Windows通常会在关机时发出砰砰声并且声音永远不会被静音。

有人可以告诉我如何暂停关机足够长的时间让我的应用程序静音吗?我可以使用一个简单的TTimer来暂停应用程序足够长的时间来运行静音,然后让Windows继续关闭。

我如何告诉Windows等待?

我注意到如果我让Firefox继续运行并尝试关机,Windows会停止并显示一条消息,“这些程序阻止窗口关闭......”并且需要单击才能强制Firefox关闭。我需要找到它。

2 个答案:

答案 0 :(得分:6)

自Windows Vista起,如果您向操作系统注册关闭原因字符串,或者您的应用程序具有顶级窗口,操作系统将无限期地等待您的程序在显示阻止应用程序屏幕时从WM_QUERYENDSESSION返回 - 或者直到用户选择强行结束程序。

以下示例代码使用Sleep模拟等待45秒。在等待的前五秒,操作系统耐心地等待,然后它才显示全屏UI。立即显示屏幕的唯一方法是立即从WM_QUERYENDSESSION返回false。但在这种情况下,您将无法恢复关机。

有关Vista及更高版本操作系统关闭行为的详细信息,请参阅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;

答案 1 :(得分:3)

您需要处理WM_QUERYENDSESSION消息。它在Windows启动关闭过程之前发送到每个应用程序。快速做你需要的 ,因为无法快速响应会导致你在FireFox中观察到的行为,这通常是设计糟糕的应用程序的标志(并且用户可能会在你获得之前终止它有机会完成)。

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;

(顺便说一下:启用/禁用声音是每用户设置,你应该非常需要干扰用户的选择。如果我是你,我会确保我的卸载程序是经过充分测试,因为任何以这种方式干扰我的声音偏好的应用都会很快从我的系统中删除。)