モダンスタンバイがサポートされた Windows 10 環境でスリープイベントが取得できない場合がある

こんにちは、Platform SDK (Windows SDK) サポートチームです。
モダンスタンバイがサポートされた Windows 10 環境でプログラムからスリープを検知する処理の動作についてご案内します。

 

現象

OS がスリープに入った状態やスリープから復帰した状態をアプリケーション上で検知する場合、RegisterSuspendResumeNotification 関数を利用して WM_POWERBROADCAST メッセージの PBT_APMSUSPEND (スリープに入る) イベントや PBT_APMRESUMEAUTOMATIC (スリープから復帰) イベントを利用します。しかし、モダンスタンバイがサポートされた Windows 10 環境では、これらメッセージは、 コネクテッドスタンバイがサポートされた Windows 8.1 とは異なるタイミングで通知される場合があります。

Windows 10 では以下のタイミングで WM_POWERBROADCAST メッセージが通知されません。

 

・ OS 起動直後、約 2 分の間スリープに入った時、および復帰時のイベントが通知されません 。

・ ログオフからログオン直後、約 2 分の間スリープに入った時、および復帰時のイベントが通知されきません 。

・ ストアアプリを起動または、タブレットモードのメニュー (画面全体を覆うメニュー) を開くと、その後 2 分間は通知が来ません。

・ ストアアプリを起動後すぐに閉じても、2 分間は通知が来ません。

・ ストアアプリを起動したまま 2 分経過した後にスリープすると、画面が OFF になってから数秒遅れてスリープが通知されます。

 

全ての通知は実際に Windows 10 がスリープに入ったタイミングで通知されており、誤った通知ではありません。 

 

回避策

モダンスタンバイがサポートされた Windows 10 において、スリープをスタートの電源ボタンや物理的な電源ボタンを押した直後の状態を通知として受け取りたい場合、ディスプレイの状態を取得することで要件を満たすことができます。ディスプレイの状態は RegisterPowerSettingNotification 関数 + GUID_CONSOLE_DISPLAY_STATE から取得することができます。

 

具体的に API を利用して確認する方法は以下の通りになります。

 

1) CallNtPowerInformation 関数 + SystemPowerCapabilities を利用し、SYSTEM_POWER_CAPABILITIES 構造体の AoAc メンバの値かモダンスタンバイ対応のデバイスであるかを判定します。True の場合はモダンスタンバイに対応しており、 False の場合は未対応になります。

 

2) 上記1) で True と判定した場合、RegisterPowerSettingNotification 関数 + GUID_CONSOLE_DISPLAY_STATE からディスプレイのオン/オフ状態を取得し、スリープ状態を判断します。実際の状態更新情報は WM_POWERBROADCAST メッセージから取得します。

 

3) ディスプレイの具体的なオン/オフ状態は WM_POWERBROADCAST メッセージ の wParam に PBT_POWERSETTINGCHANGE 値が入っている場合、lParam に格納される POWERBROADCAST_SETTING 構造体ポインタから Data メンバの値を確認します。ディスプレイの状態は Data メンバの以下の値から判断します。

0x0 – ディスプレイはオフ = スリープを実行

0x1 - ディスプレイはオン = スリープから復帰

 

関連資料

モダン スタンバイの機能の概要

https://msdn.microsoft.com/ja-jp/library/windows/hardware/mt637224(v=vs.85).aspx

 

CallNtPowerInformation function

https://msdn.microsoft.com/en-us/library/windows/desktop/aa372675(v=vs.85).aspx

 

SYSTEM_POWER_CAPABILITIES structure

https://msdn.microsoft.com/en-us/library/windows/desktop/aa373215(v=vs.85).aspx

 

RegisterPowerSettingNotification function

https://msdn.microsoft.com/en-us/library/windows/desktop/aa373196(v=vs.85).aspx

 

Power Setting GUIDs

https://msdn.microsoft.com/en-us/library/windows/desktop/hh448380(v=vs.85).aspx

 

WM_POWERBROADCAST message

https://msdn.microsoft.com/en-us/library/windows/desktop/aa373247(v=vs.85).aspx

 

PBT_POWERSETTINGCHANGE event

https://msdn.microsoft.com/en-us/library/windows/desktop/aa372722(v=vs.85).aspx

 

POWERBROADCAST_SETTING structure

https://msdn.microsoft.com/en-us/library/windows/desktop/aa372723(v=vs.85).aspx

 

PBT_APMSUSPEND event

https://msdn.microsoft.com/en-us/library/windows/desktop/aa372721(v=vs.85).aspx

 

PBT_APMRESUMEAUTOMATIC event

https://msdn.microsoft.com/en-us/library/windows/desktop/aa372718(v=vs.85).aspx