ディスプレイの電源 ON/OFF をプログラムから制御する方法 (Windows)


Windows の設定で一定時間後にディスプレイの電源を切ることは可能ですが、この記事で紹介する方法を利用すると、より柔軟に好きなタイミングでディスプレイの電源の ON/OFF を制御できます。Win32API を使います。

Windows Embedded による組み込みシステムや、日常の省エネに使えます。

マルチディスプレイの場合には、すべてのディスプレイの電源がまとめて制御されます。
個別に制御する方法を知っている人は是非教えて下さい!

方法

User32.lib の PostMessage 関数で、WM_SYSCOMMAND メッセージのパラメータに SC_MONITORPOWER を指定するとディスプレイの電源を制御できます。

具体的には以下のサンプルコードから抜粋するとこのような感じです。

DISPLAY_ON = -1
DISPLAY_OFF = 2

# ディスプレイの電源を切る
User32.PostMessage(HWND_BROADCAST,
    WM_SYSCOMMAND, SC_MONITORPOWER, DISPLAY_OFF)

Windows の設定により一定時間操作しなかったことで画面が消灯されている場合には、上記の関数の最後の引数に -1 を指定して実行し画面を点灯しても、その後直ちに画面が消灯されてしまうことがあります。その場合にはマウスの移動イベントを発行し、マウスが動かされた様に見せかけると良いです。

# マウスを動かす
inputs = [0, 1, 0, 0, 1, 0, 0].pack('l!*')  # INPUT structure
User32.SendInput(1, inputs, inputs.bytesize)

サンプルコード

Ruby によるサンプルコードです。
画面を消灯し、10秒後に再び点灯します。

ruby 2.0.0p353 (2013-11-22) [i386-mingw32] で動作確認しています。

require 'fiddle/import'
require 'fiddle/types'

module User32
    extend Fiddle::Importer

    dlload 'User32'
    include Fiddle::Win32Types

    extern "BOOL PostMessage(HWND, uint, int, int)"
    extern "uint SendInput(uint, void *, int)"
end

HWND_BROADCAST = 0xFFFF
WM_SYSCOMMAND = 0x0112
SC_MONITORPOWER = 0xF170

DISPLAY_ON = -1
DISPLAY_OFF = 2

# ディスプレイの電源を切る
User32.PostMessage(HWND_BROADCAST,
    WM_SYSCOMMAND, SC_MONITORPOWER, DISPLAY_OFF)

sleep 10

# マウスを動かす
inputs = [0, 1, 0, 0, 1, 0, 0].pack('l!*')  # INPUT structure
User32.SendInput(1, inputs, inputs.bytesize)

# 念のためにこれも実行
User32.PostMessage(HWND_BROADCAST,
    WM_SYSCOMMAND, SC_MONITORPOWER, DISPLAY_ON)

参考

カテゴリー: 記事 タグ: , , パーマリンク

コメントを残す