長時間の動画を見ている時に途中でスクリーンセーバーが立ち上がったりモニターの電源がオフになってしまったりすると気がそがれてしまいます。
ということでスクリーンセーバーおよびモニターの電源オフの抑止の方法を探しました。
本家マイクロソフトのSDK
SetThreadExecutionState の定数宣言がなされているサイト。
Win98, Win2000以降でのみ有効なんだそうですが、SetThreadExecutionStateというAPIを使います。
が、このAPIはDelphi6では宣言されていないようなので自分で宣言して使います。
上のサイトをみると動画の再生開始時にSetThreadExecutionState(ES_DISPLAY_REQUIRED
or ES_CONTINUOUS);として再生が終わったらSetThreadExecutionState(ES_CONTINUOUS);とすれば良さそうに思えたのですがだめでした。
タイマーを使って一定間隔でSetThreadExecutionState(ES_DISPLAY_REQUIRED);としなければなりませんでした。
というか、一定間隔でこのAPIを呼ぶとモニター電源オフの抑止だけでなくスクリーンセーバーも抑止されます。
タイマーを使って一定間隔でAPIを呼びますが、スクリーンセーバーの起動とモニター電源オフの間隔よりも小さくしなければなりません。
「画面のプロパティ」の「スクリーンセーバー」の設定や「電源オプションのプロパティ」の設定では最短間隔が1分になっているので30秒とか50秒間隔程度で通常は充分と思います。
ただしAPIを使うと最短間隔を1秒にすることもできるので、完璧を求めるなら0.9秒とか0.5秒間隔にする必要があるかと思います。
また下記のようにES_DISPLAY_REQUIREDとES_CONTINUOUSを一緒に使うと効き目がなくなります。
ES_DISPLAY_REQUIRED単独で使わないとなりません。
ES_CONTINUOUSは後述するシステムスタンバイの抑止のみに使います。
起動してる間モニター電源オフとスクリーンセーバーの抑止を行います
ちなみにモニターの電源がオフになっているときにSetThreadExecutionState(ES_DISPLAY_REQUIRED);を呼ぶとモニターの電源が入ります。
けれどもスクリーンセーバーが立ち上がっているときにSetThreadExecutionState(ES_DISPLAY_REQUIRED);を呼んでもスクリーンセーバーは終了しません。
スクリーンセーバーに関しては立ち上がらないようにするだけです。
タイマーを使ってSetThreadExecutionStateを呼ぶ以外に、メッセージを捕まえる方法もあるようです。
フォームにApplicationEventコンポーネントを貼り付け、オブジェクトインスペクタでOnMessageイベントをダブルクリックして下記のようにします。
この場合SetThreadExecutionStateはなくても抑止されますがこれ以後約一秒間隔で同じメッセージが飛んできてしまいます。
Vista以降だと電源管理の挙動が変わったようなのでどうなのか分かりませんが、XPではこの方法でシステムスタンバイや休止状態も同時に抑止されるようです。
ただスクリーンセーバーやモニターの電源オフを「なし」の設定にしているとこのメッセージは飛んでこないので、この方法だけでシステムスタンバイや休止状態の抑止を済ませてしまうわけにはいきません。
またこのメッセージはフォームがアクティブな状態でないと飛んでこないので、なおさらこの方法だけで済ますことはできません。
まぁ、保険的な運用ということで。
システムスタンバイや休止状態になってしまうのを防ぐためには、
とします。
抑止を解除するには
とします。
モニター電源オフの抑止とは違い、タイマーなどを使っての定期的な呼び出しを繰り返す必要はありません。
一度SetThreadExecutionState(ES_SYSTEM_REQUIRED or ES_CONTINUOUS);としておけば、それ以降SetThreadExecutionState(ES_CONTINUOUS);を呼び出すまでシステムスタンバイは抑止されます。
アプリケーションを起動している間スタンバイの抑止をしたいのであれば起動時のOnCreateイベントでSetThreadExecutionState(ES_SYSTEM_REQUIRED
or ES_CONTINUOUS);としておいて終了時のOnDestroyイベントでSetThreadExecutionState(ES_CONTINUOUS);とすればよいということです。
ちなみにタイマーなどでSetThreadExecutionState(ES_SYSTEM_REQUIRED);を定期的に呼んでもOKでした。
※以前試したときにはだめで、そのようにも書いたのですが改めて試してみるとちゃんとシステムスタンバイは抑止されています。
どうやら何かをかん違いしていたようです。
スクリーンセーバーの抑止、モニターの電源オフの抑止、システムスタンバイの抑止を一緒に行おうとして
というようにまとめてしまうと、システムスタンバイの抑止は効きますがスクリーンセーバーの抑止とモニターの電源オフの抑止は効きません。
タイマーを使って定期的に呼んでも結果は同じです。
以下のようにES_CONTINUOUSを外してタイマーを使って定期的に呼び出すと両方まとめて抑止されます。
スクリーンセーバーおよびモニター電源オフの抑止にはES_CONTINUOUSを一緒に指定してはならないということのようです。
もしかしたらVista以降だとES_CONTINUOUSを併用してもOKなのかも知れませんが、少なくともXPではだめなようです。
scv - スクリーンセーバー抑止プログラム。
上記のサンプルプログラムに手を加えてタスクトレイに常駐するようにしたプログラムです。
scvx - scvに付加機能をつけた版。
scvに、登録したプログラムが起動していたら抑止する機能を足したプログラムです。