Windowsのデフォルトでは、省エネのためしばらく操作しないとディスプレイ出力が停止します。
マウス操作などすれば再度ディスプレイが付きますが、常駐アプリなどを作成する場合、プログラムからディスプレイをONにしたい場合があります。
そんなときは、PostMessageでWM_SYSCOMMANDメッセージを送り、wParamにSC_MONITORPOWER、lParamに-1をセットすればOKです【方法A】。
http://msdn.microsoft.com/en-us/library/ms646360(VS.85).aspx
しかしこの方法では、WindowsXPなどの環境で、一瞬ディスプレイが付いたあと、すぐに再度OFFになってしまう場合があります。
これについて解析している方もいらっしゃいましたが、ここでは別の方法として、「マウスを動かす」ことによって省電力モードを解除してみましょう【方法B】。
方法AとBの両方のソースをご紹介します。C#でWPFな環境を想定しています。
なお、方法Aでは引数を変えるだけでディスプレイ電源OFFも可能です。
const int HWND_BROADCAST = 0xffff;
const int WM_SYSCOMMAND = 0x0112;
const int SC_MONITORPOWER = 0xF170;
const int INPUT_MOUSE = 0;
const int INPUT_KEYBOARD = 1;
const int MOUSEEVENTF_MOVED = 0x0001;
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct INPUT
{
public int type;
public MOUSEINPUT mi;
}
[DllImport("user32.dll")]
public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
//【方法A】
void WakeupDisplayA()
{
//最後の引数は、1=省電力モード、2=ディスプレイ停止、-1=省電力モードから復帰
PostMessage((IntPtr)HWND_BROADCAST, (IntPtr)WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)(-1));
}
//【方法B】
void WakeupDisplayB()
{
//適当に動かす
INPUT[] inputs = new INPUT[2];
inputs[0].mi.dx = 10;
inputs[0].mi.dwFlags = MOUSEEVENTF_MOVED;
inputs[1].mi.dx = -10;
inputs[1].mi.dwFlags = MOUSEEVENTF_MOVED;
SendInput(2, inputs, System.Runtime.InteropServices.Marshal.SizeOf(inputs[0]));
}