9

いくつかの背景: 私はいくつかのフォームなどを含むアプリケーションを作成しています。ユーザーはほとんどの機能を使用するためにログインする必要がありますが、これは今まで問題なく機能していました。ただし、現在、クライアントは、一定の非アクティブ時間後にユーザーをログアウトするように要求しています。問題は、ユーザーがアプリケーションではなく、コンピューター上で引き続きアクティブになる可能性があることです。明確にするために、ユーザーがまだデスクトップと対話している場合でも、ユーザーがアプリケーションで非アクティブになっているときにログアウトする必要があります。

まず、これはかなり単純だと思いました。最後のアクションの時間を覚えておいて、タイマーで現在の時間と継続的に比較し、経過時間が許可された時間よりも長い場合はユーザーをログアウトします。しかし、最後のアクション時間を見つけるのはそれほど簡単ではないかもしれないことに気付きました...

もちろん、次のようなものをコピーして貼り付けることができます

Program.LastActionTime = DateTime.Now;

すべての OnChange、OnClick などのイベントで...しかし、これはアプリケーションのサイズのために大量の作業になるだけでなく...非常に悪い習慣でもあり、そうなると確信しています少なくとも一度は忘れてしまい、全体が信頼できなくなりました (そして壊れているように見えると、バグを再現することはほとんど不可能です!)

それで、より良い方法はありますか?

4

6 に答える 6

6

One approach that I've used in the past, create a MessageFilter on your application form and check for certain types of events that indicate user activity:

 public class UserActivityFilter : IMessageFilter
 {
        // Define WinAPI window message values (see pinvoke.net)
        private int WM_LBUTTONDOWN = 0x0201;
        private int WM_MBUTTONDOWN = 0x0207;
        private int WM_RBUTTONDOWN = 0x0204;
        private int WM_MOUSEWHEEL = 0x020A;
        private int WM_MOUSEMOVE = 0x0200;
        private int WM_KEYDOWN = 0x0100;

        public bool PreFilterMessage(ref Message m)
        {
            if (m.Msg == WM_LBUTTONDOWN || m.Msg == WM_MBUTTONDOWN || m.Msg == WM_RBUTTONDOWN || m.Msg == WM_MOUSEWHEEL || m.Msg == WM_MOUSEMOVE || m.Msg == WM_KEYDOWN)
            {
                //User activity has occurred
                // Reset a flag / timer etc.
            }
            return false;
        }
  }

Then in the Main() method of the form, BEFORE the call to Run():

Application.AddMessageFilter(new UserActivityFilter());

One caveat, adding a complex message filter or adding multiple separate filters can slow down the responsiveness of your application.

于 2009-09-14T13:20:20.930 に答える
2

In your Program.CS file, you can handle the Application.Idle event and reset your timer there. See:

http://msdn.microsoft.com/en-us/library/system.windows.forms.application.idle.aspx

于 2009-09-14T13:21:43.423 に答える
1

You can override WndProc, update Program.LastActionTime on each relevant Keyboard/Mouse event message.

于 2009-09-14T13:21:16.983 に答える
0

MouseMove および KeyPressed イベントでイベント ハンドラーをフックし、そのイベント内でフォーカスを確認しますか?

于 2009-09-14T13:03:09.023 に答える
0

一般に、生のユーザー入力ではなく、アプリケーション ロジックからこの情報を取得するのが最善の方法ですが、この情報を提供できる柔軟なインフラストラクチャ (おそらくコマンド パターンを使用) がないことを前提としています。

そのため、ハンドラーをメイン フォームに登録することをお勧めします。クリックまたはキー イベントを受信した場合 (このためにForm.KeyPreviewを有効にします)、ユーザーはアクティブであり、非アクティブ時間をリセットできます。

于 2009-09-14T13:07:14.863 に答える
0

すべてのウィンドウ フォームが継承する基本クラスを作成できます。基本クラスでは、KeyPress または Click ごとにタイムアウトを確認してリセットします。

于 2009-09-14T13:07:32.627 に答える