web-dev-qa-db-ja.com

非アクティブなユーザーを検出する方法

Windowsアプリケーションで非アクティブ(アイドル)ユーザーを検出する方法は?ユーザーからの入力(キーボード、マウス)が一定時間ない場合、アプリケーションをシャットダウンしたいと思います。

27
Harriv

ユーザーのアイドル時間を追跡するには、キーボードとマウスのアクティビティをフックします。ただし、システム全体のメッセージフックのインストールは非常に侵襲的な作業であり、フックDLLをすべてのプロセスにロードする必要があるため、可能であれば回避する必要があることに注意してください。

別の解決策は、 GetLastInputInfo API関数を使用することです(アプリケーションがWin2000(およびそれ以降)のマシンで実行されている場合)。 GetLastInputInfoは、最後に入力されたイベントの時刻(ミリ秒単位)を取得します(キーボードまたはマウスのどちらからでも、最後に検出されたユーザーアクティビティが受信されたとき)。

これが簡単な例です。 SecondsIdle関数は、ユーザーアクティビティなしで秒数を返します(OnTimerコンポーネントのTTimerイベントで呼び出されます)。

~~~~~~~~~~~~~~~~~~~~~~~~~
function SecondsIdle: DWord;
var
   liInfo: TLastInputInfo;
begin
   liInfo.cbSize := SizeOf(TLastInputInfo) ;
   GetLastInputInfo(liInfo) ;
   Result := (GetTickCount - liInfo.dwTime) DIV 1000;
end;

procedure TForm1.Timer1Timer(Sender: TObject) ;
begin
   Caption := Format('System IDLE last %d seconds', [SecondsIdle]) ;
end;

http://delphi.about.com/od/adptips2004/a/bltip1104_4.htm

43
James Campbell
9
Tommy Andersen

スクリーンセーバーが起動しようとすると、アプリケーションはコマンドIDとしてWM_SYSCOMMANDを含むSC_SCREENSAVEメッセージを受け取ります。モニターがブランクになりそうなときは、SC_MONITORPOWERコマンドIDもあります(これもWM_SYSCOMMANDメッセージです)。

編集:コメントを見ると、serがネイティブであるかどうかではなく、applicationが非アクティブであるかどうかを気にしないようです。

これは簡単。アプリが最小化されている場合、ユーザーはアプリを操作していません。アプリがフォアグラウンドアプリケーションでない場合は、それも優れた指標です。

また、ポンプ内のメッセージに注意を払って、アプリにユーザー入力メッセージがあったかどうかを確認することもできます。C++では、ポンプにコードを追加するのは簡単です。 wH_GETMESSAGEフックを使用してポンプを監視します TApplicationが実装するメッセージループにフックします。またはGetLastInputInfo

6
John Knoeller

このSecondsIdleはまったく機能しません。方法は、ユーザーがマウスまたはキーボードを入力するたびにリセットされる2番目の変数と組み合わせたTTimerを使用することです。