質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

13150閲覧

一定時間操作をしなかったときにスクリーンオフにする方法について

TOMO6181

総合スコア39

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2016/10/08 11:45

###前提・実現したいこと
一定時間何も操作をしなかったときにスクリーンオフにして、
スクリーンオフの状態でマウスを動かしたりクリックする等、何らかの
操作をしたときに再度スクリーンオンにする機能を実現しようとしています。
一定時間というのは、入力者が任意に決められる仕様です。

###試したこと
1秒間隔でタイマー割り込みを行ってその割り込み内でGetLastInputInfoメソッドを使い、
最後にイベントが発生した時間を取得して一定時間以上経過しているならスクリーンオフにする、
という方法を考えました。
しかし、スクリーンオフにするまでの時間は入力者が任意で決められる仕様であるため、
3.5秒後等、細かい指定をされると1秒間隔のポーリングでは実現できません。
また、0.1秒間隔でポーリングをするとタイマー割り込みが多すぎてパフォーマンスが
下がってしまいます。

###補足情報(言語/FW/ツール等のバージョンなど)
C#のWPFで実装しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

いわゆるスクリーンセーバーですね。難しく考えすぎのようです。
単純にタイマーを1個用意して指定時間のタイムアップイベントでスクリーンオフにするというプログラムを書き、マウスやキー入力のイベントハンドラ内でタイマーカウントを0に戻す(リセットして再スタート)、というやり方でできます。パフォーマンスに対するコストはほとんど無視できる程度です。

投稿2016/10/08 13:25

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TOMO6181

2016/10/09 03:55

ありがとうございます。 ただ、今作成しているアプリケーションが画面数、ボタン数等が多めで 全イベントハンドラ内にタイマーカウントを0に戻す処理を入れるのは 少々厳しいです。 説明不足で申し訳ありません。
catsforepaw

2016/10/09 05:20

その場合はディスパッチ前のメッセージを処理する部分に組み込みます。WindowsのGUIアプリは、必ずメッセージループなるものが存在していて、受信したウィンドウメッセージを各ウィンドウ・コントロールに配信(ディスパッチ)しています。マウスやキー入力もウィンドウメッセージという形でアプリが受け取るので、それを判別して処理すれば良いことになります。 C#でもその仕組みは提供されていて、フォームアプリならApplicationクラスのAddMessageFilterメソッドがそれに該当しますが、WPFのApplicationクラスはだいぶ違うようで、あまり深くいじったことがないのですぐには判りませんが、何かその手の機能が用意されていると思います。 あるいはローカルフックでマウスやキー入力を監視する方法もあります。
TOMO6181

2016/10/09 12:29

大変丁寧な解説ありがとうございます。 ウィンドウメッセージを受け取る方法で調べたところ、以下の方法でうまくいきました。 ================================================== /// <summary> /// ウィンドメッセージを受け取るイベントのセット /// </summary> private void SetAddHook() { this.Loaded += delegate { HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); source.AddHook(WindowProc); }; } /// <summary> /// ユーザーが文字キーを押したことを示します。 /// </summary> private const int WM_CHAR = 0x0102; /// <summary> /// マウス カーソルが移動したことを示します。 /// </summary> private const int WM_MOUSEMOVE = 0x0200; /// <summary> /// 左のマウス ボタンがいつ押されたかを示します。 /// </summary> private const int WM_LBUTTONDOWN = 0x0201; /// <summary> /// ウィンドウメッセージを受け取るイベント /// </summary> /// <param name="hwnd">ハンドル</param> /// <param name="msg">メッセージ ID</param> /// <param name="wParam">メッセージの wParam 値。</param> /// <param name="lParam">メッセージの lParam 値。</param> /// <param name="handled">メッセージが処理されたかどうかを示す値。</param> /// <returns>特定のメッセージに依存する適切な戻り値。 </returns> private static IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch (msg) { case WM_CHAR: Console.WriteLine("文字キーが押されました。"); // タイマーを再起動 TimerManage.TimerReStart(); break; case WM_MOUSEMOVE: Console.WriteLine("マウスカーソルが移動しました。"); // タイマーを再起動 TimerManage.TimerReStart(); break; case WM_LBUTTONDOWN: Console.WriteLine("左のマウス ボタンが押されました。"); // タイマーを再起動 TimerManage.TimerReStart(); break; default: break; } return hwnd; } ================================================ 上記のAddHookイベントで、メッセージウィンドウを登録することができました。 先のtoki_td様には申し訳ないですが、ここまで詳しい回答をお教えして頂きました catsforepaw様にベストアンサーを差し上げたいと思います。
guest

0

スクリーンがオフのタイマーを動かしているとき普段は1秒単位でカウントして残り時間が1秒以下になったら現在のタイマーを停止、残り時間分のタイマーを作成して時間が経過したらスクリーンオフ、でいいとおもいます。

投稿2016/10/08 12:30

toki_td

総合スコア2850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TOMO6181

2016/10/09 12:45 編集

ありがとうございます。 タイマーを2つ使うという方法は盲点でした。 試してみようと思います。 追記 申し訳ありません。上記catsforepaw様の回答で解決致しましたので catsforepaw様の方をベストアンサーにさせて頂きました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問