如果在一段时间内未使用,请禁用c#表单? [英] Disable a c# form if not used for a certain duration?

查看:84
本文介绍了如果在一段时间内未使用,请禁用c#表单?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有4个表单的ac #project这些表单之一是主要表单我想让主表单被禁用(主表单上的所有控件)如果我不使用它(不要在它上面工作) )在一定的持续时间内,例如在10分钟内,我使用计时器并禁用主表单控件,但如果我使用它也会这样做

这是我的代码

i have a c# project that have 4 forms one of these form is main form i want to make the main form is disabled (all controls on the main form) if i don't use it(don't work on it) in certain duration of time for example in 10 minutes, i use the timer and it disable the main form controls but it do this also if i work on it
this is my code

private void main_Load(object sender, EventArgs e)
{
    timer1.Interval = 10000; 
    timer1.Enabled = true; // start timer

}







private void timer1_Tick(object sender, EventArgs e)
{
    timer1.Enabled = false; // stop timer
    lib_bt.Enabled = false;
}

推荐答案

嗨honar.cs



你的方法不起作用(或将很难维护)。想一想:如何在我的应用程序的任何用户输入上重置计时器。你最终会得到很多处理程序(因为你使用WinForms而不是WPF,所以没有隧道/冒泡事件)。所以忘记天真的计时器aproach。



您可以使用的是某种 Application.Idle 处理,但这又不是为你的useccase设计的,我认为这是一个黑客(但你可能想看看检测应用程序空闲状态 [ ^ ]



另一个aproach会使用钩子通过鼠标或键盘检测用户输入 - 这肯定会起作用,但可能很复杂。



我认为最简单的方法是调用 GetLastInputInfo - http://msdn.microsoft.com/en-us/library/windows/desktop/ms646302(v = vs.85)的.aspx [ ^ ]





你可以编组这个WinAPI函数(和它用作参数的结构如下:



Hi honar.cs

Your approach won't work (or will be very difficult to maintain). Think about: "How to reset the timer on ANY user input to my application". You will end up with a lot of handlers (and since you use WinForms and not WPF there are no tunneling/bubbling Events). So forget about the "naive timer aproach".

What you could use is some kind of Application.Idle handling, but again this was not designed for your useccase and I would consider it a hack (but you may want to a look at Detecting Application Idleness[^]

Another aproach would use hooks to detect USER Input through mouse or keyboard - this will work for sure but maybe to complicated.

I think easiest aproach is to call GetLastInputInfo - http://msdn.microsoft.com/en-us/library/windows/desktop/ms646302(v=vs.85).aspx[^]


You could marshall this WinAPI function (and the structure it uses as parameter) like this:

[DllImport("user32.dll")]
public static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

public struct LASTINPUTINFO
{
    [MarshalAs(UnmanagedType.U4)]
    public int cbSize;
    [MarshalAs(UnmanagedType.U4)]
    public int dwTime;
}





Timer.Tick 中调用此函数( Elapsed)事件处理程序, - 将您通过 dwTime 属性得到的滴答计数与当前滴答计数进行比较,如果超过您的限制则停用您的表单(或任何您想要的做)。不要忘记重新设置(或根据您的要求重新启用整个东西)。



我忘了添加一个示例来调用API函数:





Call this function in a Timer.Tick (Elapsed) event-handler, - compare the tick count you get through the dwTime propery with the current tick count, if it's over your limit deactivate your Form (or whatever you want to do). Don't forget to re-set (or re-enable the whole thing according to your requirements).

I forgot to add an example to call the API function:

public int GetIdleTimeInSeconds()
{
    int idletime = 0;
    idletime = 0;
    LASTINPUTINFO lastInputInf = new LASTINPUTINFO();
    lastInputInf.cbSize = Marshal.SizeOf(lastInputInf);
    lastInputInf.dwTime = 0;

    if (GetLastInputInfo(ref lastInputInf))
    {
        idletime = Environment.TickCount - lastInputInf.dwTime;
    }

    if (idletime != 0)
    {
        return idletime / 1000;
    }
    else
    {
        return 0;
    }
}





所以将它与我创建的可运行示例(快速和肮脏)结合在一起。但是这会对当前用户会话的任何输入作出反应,而不仅仅是对你的表单...(如果你想要的话,不是shure) - 所以它就像一个屏幕保护程序。





So bringing it all together with a runnable example I created (quick & dirty). But this will react to "any" input for the current user session not only to your form... (not shure if you want that) - so it works like a screensaver.

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace OnIdleTimeICreateExamples
{
    static class Program
    {
        class SampleForm : Form
        {
            // Let's import the GetLastInputInfo function from user32.dll (Windows-API library)
            [DllImport("user32.dll")]
            static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

            // ... this function takes a pointer to the LASTINPUTINFO structure,
            // so to call the function we need a C# representation of it.
            // We build it according to the documentation of the function found at  http://msdn.microsoft.com/en-us/library/windows/desktop/ms646302(v=vs.85).aspx
            [StructLayout(LayoutKind.Sequential)]
            public struct LASTINPUTINFO
            {
                [MarshalAs(UnmanagedType.U4)]
                public int cbSize;
                [MarshalAs(UnmanagedType.U4)]
                public int dwTime;
            }

            Timer m_timerCheckForElapsedIdleTime;
            int m_iTargetIdleSeconds = 10; 

            public SampleForm()
            {
                // Setup our timer
                m_timerCheckForElapsedIdleTime = new Timer();
                m_timerCheckForElapsedIdleTime.Interval = 1000; //let's check every second if idle time was reached
                m_timerCheckForElapsedIdleTime.Tick += m_timerCheckForElapsedIdleTime_Tick;
                
                // create a textbox so we can play with the example and simulate "input"
                TextBox textbox = new TextBox();

                Controls.Add(textbox);

                // Start checking:
                m_timerCheckForElapsedIdleTime.Start();
            }

            void m_timerCheckForElapsedIdleTime_Tick(object sender, EventArgs e)
            {
                // Let's have a look if we hit the idle time target
                if (GetIdleTimeInSeconds() > m_iTargetIdleSeconds)
                {
                    // do what you want, we do something we can "see" easily
                    BackColor = Color.Red;
                }
                else
                {
                    BackColor = SystemColors.Control;
                }
            }

            public int GetIdleTimeInSeconds()
            {
                int idletime = 0;
                idletime = 0;
                LASTINPUTINFO lastInputInf = new LASTINPUTINFO();
                lastInputInf.cbSize = Marshal.SizeOf(lastInputInf);
                lastInputInf.dwTime = 0;

                if (GetLastInputInfo(ref lastInputInf))
                {
                    idletime = Environment.TickCount - lastInputInf.dwTime;
                }

                if (idletime != 0)
                {
                    return idletime / 1000;
                }
                else
                {
                    return 0;
                }
            }
        }

        [STAThread]
        static void Main()
        {
            // Let's run our sample form 
            Application.Run(new SampleForm());
        }
    }
}







希望这有帮助,快乐的编码!



Johannes




Hope this helps, happy coding!

Johannes


设置类级整数变量

Set up a class level integer variable
private int waitForDisable = 10 * 60;



并更改您的间隔:


And change your interval:

timer1.Interval = 1000;

注意:10000是10秒,以毫秒为单位,而不是一分钟......没有什么比这更糟的了而不是 错误的 评论...



然后在您的Tick事件中,检查waitForDisable:

NOTE: 10000 is ten seconds in milliseconds, not one minute...there is nothing worse than a wrong comment...

Then in your Tick event, check waitForDisable:

if (waitForDisable > 0)
   {
   waitForDiable--;
   if (waitForDisables == 0)
      {
      // Disable the form
      ...
      }
   }

然后,每当用户对您的表单做某事时,您所要做的就是将waitForDisable设置回10 * 60。

Then all you have to do is set waitForDisable back to 10 * 60 every time the user "does something" with your form.


这篇关于如果在一段时间内未使用,请禁用c#表单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆