3

在 Windows XP 上,我可以在按下笔记本电脑的电源按钮时检测到事件。获得 APMQUERYSUSPEND 事件的条件是 [控制面板-> 电源选项-> 系统设置-> 当我按下电源按钮时-> 睡眠] 的选项必须更改为“睡眠”。

MainFrm::OnPowerBroadcast(WPARAM wParam, LPARAM lParam)

{

         switch (wParam)

         {

                       case PBT_APMQUERYSUSPEND:

                       // Ask question whether to power off or not

                       // If not, return BROADCAST_QUERY_DENY

                       return BROADCAST_QUERY_DENY;

         }

但是从 Windows 7 开始,我没有任何线索可以检测到该事件。基于 Windows 7,删除了 APMQUERYSUSPEND 事件。即使我尝试了 SetThreadExecutionState API 来阻止关闭,它也不起作用。 http://msdn.microsoft.com/ko-kr/library/windows/desktop/aa372716(v=vs.85).aspx

您知道按下电源按钮时捕捉事件的任何想法吗?

谢谢。

4

1 回答 1

4

根据 Microsoft 的文档,一旦启动睡眠事件,就无法再中断它。这里有一个关于 Windows Vista/7 电源控制的内容非常丰富的演示文稿。还有一种方法可以捕获睡眠按钮事件。我将在示例中使用 C# 语法

首先,RegisterHotKey(this.Handle, 0, 0x4000, 0x5F)从 user32.dll API 调用挂钩睡眠键。然后覆盖你的程序的WndProc方法(取决于你使用的语言和环境,有不同的方法可以做到这一点)并监听热键消息 312h。收到它后,立即SetThreadExecutionState(EXECUTION_STATE.ES_AWAYMODE_REQUIRED | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS) 从 kernel32.dll API 调用以防止 Windows 启动睡眠事件。一段时间后(如果您希望系统能够再次休眠),您可以调用SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS).

请注意,SetThreadExecutionState如果已经启动了睡眠程序,则不会产生任何影响,这就是为什么上述对于电源按钮无法执行的原因,据我所知,它不能被钩住(如果有人真的知道这样做的方法那个,请告诉我!)。这也可能是为什么SetThreadExecutionState不适合你。

常数是:

        ES_CONTINUOUS = 0x80000000,
        ES_SYSTEM_REQUIRED = 1,
        ES_AWAYMODE_REQUIRED = 0x00000040
于 2013-08-22T23:58:17.450 回答