作業をしているときにどうしたものかこうしたものか、マウスを動かすこともなくキーボードを叩くことなく考えているときにスクリーンセーバーが起動することはよくあります。こんなときにスクリーンセーバーが起動しないようにするにはどうすればよいのでしょうか? スクリーンセーバーをOFFにする! もちろんそれ以外の方法でです。
こんなページを見つけました。
スクリーンセーバーが起動する前に、Windowsはアクティブなアプリケーションに対してSC_SCREENSAVEを指定したWM_SYSCOMMANDメッセージを送ります。このときにDefWindowProc()関数を呼ばずに何もしなければスクリーンセーバーを起動させないことができるのです。スクリーンセーバーを起動させないときは0以外の値を返さなければなりません。
1 2 3 4 5 6 7 8 9 |
switch( message ) { case WM_SYSCOMMAND: if( wParam == SC_SCREENSAVE ) { return 1; } break; // 以下は省略 } |
ではC#ならどうなるでしょうか? 以下のコードで実験してみるとスクリーンセーバーは起動しません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } int WM_SYSCOMMAND = 0x0112; int SC_SCREENSAVE = 0xf140; protected override void WndProc(ref Message m) { if(m.Msg == WM_SYSCOMMAND && (int)m.WParam == SC_SCREENSAVE) { m.Result = (IntPtr)1; return; } base.WndProc(ref m); } } |
ただこの方法はリンク先のページにも書いてありますが、「WM_SYSCOMMANDはアクティブなアプリケーションにしか送られてこないので、自分がアクティブなときにしか抑制できません」。
ではアクティブではない場合であってもスクリーンセーバーを抑止するためにはどうすればいいのでしょうか?
プログラミング/C#/スクリーンセーバー起動の回避 – 武内@筑波大 では以下のようなコードが紹介されていました。
1分以内にマウスカーソルが動けばスクリーンセーバーは起動しない。だったら同じような状態を作り出せないかということで書かれたコードです。実際にはマウスカーソルを動きません。ダミーのインプットを送り続けている限りスクリーンセーバーの起動は阻止できるとのこと。
実際に下記プログラムを実行してみたが、スクリーンセーバーは起動しませんでした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
public partial class Form1 : Form { Timer Timer = new Timer(); public Form1() { InitializeComponent(); Timer.Interval = 30 * 1000; Timer.Tick += Timer_Tick; Timer.Start(); } private void Timer_Tick(object sender, EventArgs e) { PreventScreenSaverFromStarting(); } [StructLayout(LayoutKind.Sequential)] struct MOUSEINPUT { public int dx; public int dy; public uint mouseData; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] struct KEYBDINPUT { ushort wVk; ushort wScan; uint dwFlags; uint time; IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] struct HARDWAREINPUT { uint uMsg; ushort wParamL; ushort wParamH; } [StructLayout(LayoutKind.Explicit)] struct INPUT { [FieldOffset(0)] public int type; [FieldOffset(4)] //* public MOUSEINPUT mi; [FieldOffset(4)] //* public KEYBDINPUT ki; [FieldOffset(4)] //* public HARDWAREINPUT hi; } const int INPUT_MOUSE = 0; [DllImport("user32.dll", SetLastError = true)] static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize); void PreventScreenSaverFromStarting() { INPUT input = new INPUT(); input.type = INPUT_MOUSE; input.mi = new MOUSEINPUT(); input.mi.dwExtraInfo = IntPtr.Zero; input.mi.dx = 0; input.mi.dy = 0; input.mi.time = 0; input.mi.mouseData = 0; input.mi.dwFlags = 0x0001; // MOVE (RELATIVE) int cbSize = Marshal.SizeOf(typeof(INPUT)); uint r = SendInput(1, ref input, cbSize); } } |