スクリーンセーバー起動の回避 の変更点
更新- 追加された行はこの色です。
- 削除された行はこの色です。
- プログラミング/C#/スクリーンセーバー起動の回避 へ行く。
- プログラミング/C#/スクリーンセーバー起動の回避 の差分を削除
[[公開メモ]] #contents * スクリーンセーバー起動の回避 [#o8cb7cc4] 長時間ユーザーの入力なしに画面表示を行うことを目的としたアプリケーション、 例えばスライドショーソフト、ビデオ再生ソフト、ゲームパッドのみを用いる ゲームソフト、計器の状態を表示し続ける測定ソフトなどでは、その動作中に スクリーンセーバーが起動してしまうと不都合な場合がある。 これを回避するための方法をインターネット上で探すと~ http://d.hatena.ne.jp/NyaRuRu/20080925/p1 - SetThreadExecutionState を使う - WM_SYSCOMMAND メッセージを補足する(フォアグランドアプリケーションのみ可能) - SetCursorPos でカーソル位置を移動させる - ・・・ などなどいろいろ記述が見つかるが、 - Windows Vista - 再開時にパスワードが必要 の条件が重なるとなかなかうまく行かない。 * 解決法 [#fd875e32] 探し回ったあげく、ここにあった方法はそれなりの効果があった。 http://groups.google.com/group/microsoft.public.win32.programmer.kernel/browse_thread/thread/976caa9de9a5e359 以下の関数を定期的に(1分以下の間隔で)呼んでやることで スクリーンセーバーは起動しない。 ただ、マウスカーソルが始終プルプル動くので、 フルスクリーンでマウスカーソルを消して実行しているような、 スライドショーやビデオ再生ソフトくらいでしか使えない? LANG:C#(linenumber) void PreventScreenSaverFromStarting() { Point pos = Cursor.Position; Cursor.Position = new Point(pos.X + 1, pos.Y + 1); if ( Cursor.Position == pos ) Cursor.Position = new Point(0, 0); INPUT input = new INPUT(); input.type = INPUT_MOUSE; input.mi = new MOUSEINPUT(); input.mi.dwExtraInfo = IntPtr.Zero; // mouse co-ords: top left is (0,0), bottom right is (65535, 65535) // convert screen co-ord to mouse co-ords... Random ran = new Random(); input.mi.dx = ran.Next(0, 2000); input.mi.dy = ran.Next(0, 3000); input.mi.time = 0; input.mi.mouseData = 0; input.mi.dwFlags = 0x0001 | 0x8000; // MOVE | ABSOLUTE int cbSize = Marshal.SizeOf(typeof(INPUT)); uint r = SendInput(1, ref input, cbSize); } #region Win32 API [StructLayout(LayoutKind.Sequential)] struct MOUSEINPUT { public int dx; public int dy; public uint mouseData; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } const int INPUT_MOUSE = 0; [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; } [DllImport("user32.dll", SetLastError = true)] static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize); [FlagsAttribute] public enum EXECUTION_STATE: uint { ES_SYSTEM_REQUIRED = 0x00000001, ES_DISPLAY_REQUIRED = 0x00000002, // Legacy flag, should not be used. // ES_USER_PRESENT = 0x00000004, ES_CONTINUOUS = 0x80000000, } [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); #endregion * 改善案 [#p9cee7ab] 手元で試した限り、マウスカーソルを動かさなくても ダミーのインプット(実際にはカーソルを動かさない) を送り続けている限りスクリーンセーバーの起動は 阻止できるみたいだった。 これならカーソルが勝手に動くこともないので使いやすそう。 LANG:C#(linenumber) 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); } * コメント [#n7785aed] #article_kcaptcha **anPYAWsAyVSoshu [#j94ef65c] >[Gavin] (2013-01-04 (金) 05:54:56)~ ~ I'm rlaely into it, thanks for this great stuff!~ // #comment_kcaptcha
Counter: 25747 (from 2010/06/03),
today: 2,
yesterday: 8