4

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 never gets muted.

Can someone please tell me how to pause the shutdown long enough for my app to mute the sound? I can use a simple TTimer to pause the app long enough for it to run the muting and then let Windows get on with shutting down.

How do I tell Windows to wait though?

I notice that if I leave Firefox running and try to shutdown, Windows stops with a message, "These programs are preventing windows closing..." and needs a click to force Firefox to close. I need to find that.

4

2 回答 2

7

从 Windows Vista 开始,如果您向操作系统注册了关闭原因字符串,或者您的应用程序具有顶级窗口,则操作系统将无限期地等待您的程序从WM_QUERYENDSESSION显示阻塞应用程序屏幕返回 - 或直到用户选择强制结束当然是程序。

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

有关 Vista 及更高版本操作系统关闭行为的详细信息,请参阅文档

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;
于 2013-08-21T01:19:23.167 回答
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;

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

于 2013-08-21T00:11:44.137 回答