在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
你知道在按下电源按钮时捕捉事件的想法吗?
感谢。
答案 0 :(得分:4)
根据Microsoft的文档,一旦启动睡眠事件,就不再可能中断睡眠事件。在Windows Vista / 7电源控制here上有一个非常丰富的演示文稿。 仍有一种方法可以捕获睡眠按钮事件。 我将在我的示例中使用C#语法:
首先,从user32.dll API调用RegisterHotKey(this.Handle, 0, 0x4000, 0x5F)
来挂钩睡眠密钥。然后覆盖程序的WndProc
方法(取决于您使用的语言和环境,有不同的方法)并监听热键消息312h。收到后,请立即从kernel32.dll API调用SetThreadExecutionState(EXECUTION_STATE.ES_AWAYMODE_REQUIRED | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS)
以防止Windows启动睡眠事件。一段时间后(如果您希望系统能够再次入睡),您可以拨打SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS)
。
请注意,如果已经启动了睡眠过程,SetThreadExecutionState
将没有任何效果,这就是为什么上面的电源按钮无法做到的原因,据我所知,这个按钮无法挂钩(如果有人真的知道如何做到这一点,请告诉我!)。这也可能是SetThreadExecutionState
无效的原因。
常数是:
ES_CONTINUOUS = 0x80000000,
ES_SYSTEM_REQUIRED = 1,
ES_AWAYMODE_REQUIRED = 0x00000040