扭动鼠标

时间:2008-08-05 02:51:37

标签: c# winapi mouse

行。这是一个虚荣的应用程序,但我今天在工作中有一个情况,我在训练课,机器设置锁定每10分钟。好吧,如果培训师对谈话感到兴奋 - 而不是更换幻灯片 - 机器会锁定。

我想写一个小应用程序,除了任务栏图标之外什么都不做,除了每4分钟将鼠标移动1个像素。

我可以用Delphi(我强大的语言)以3种方式做到这一点,但我正在转向C#工作,我想知道那里阻力最小的路径。

6 个答案:

答案 0 :(得分:23)

适用于C#3.5

没有notifyicon因此您需要手动在任务管理器中终止此应用程序

using System;
using System.Drawing;
using System.Windows.Forms;

static class Program
{
    static void Main()
    {
        Timer timer = new Timer();
        // timer.Interval = 4 minutes
        timer.Interval = (int)(TimeSpan.TicksPerMinute * 4 / TimeSpan.TicksPerMillisecond);
        timer.Tick += (sender, args) => { Cursor.Position = new Point(Cursor.Position.X + 1, Cursor.Position.Y + 1); };
        timer.Start();
        Application.Run();
    }
}

答案 1 :(得分:12)

执行此操作的“正确”方法是响应WM_SYSCOMMAND消息。在C#中,这看起来像这样:

protected override void WndProc(ref Message m)
{
    // Abort screensaver and monitor power-down
    const int WM_SYSCOMMAND = 0x0112;
    const int SC_MONITOR_POWER = 0xF170;
    const int SC_SCREENSAVE = 0xF140;
    int WParam = (m.WParam.ToInt32() & 0xFFF0);

    if (m.Msg == WM_SYSCOMMAND &&
        (WParam == SC_MONITOR_POWER || WParam == SC_SCREENSAVE)) return;

    base.WndProc(ref m);
}

根据MSDN,如果Vista或更高版本的策略启用了屏幕保护程序密码,则无效。大概以编程方式移动鼠标也会被忽略,尽管我还没有对此进行过测试。

答案 2 :(得分:10)

当我在家工作时,我将鼠标线连接到从左到右摆动的桌面风扇。它使鼠标保持移动并使工作站无法进入睡眠状态。

答案 3 :(得分:2)

这样的事情应该有用(但是,你 想要改变间隔)。

public Form1()
{
    InitializeComponent();
    Timer Every4Minutes = new Timer();
    Every4Minutes.Interval = 10;
    Every4Minutes.Tick += new EventHandler(MoveNow);
    Every4Minutes.Start();
}

void MoveNow(object sender, EventArgs e)
{
    Cursor.Position = new Point(Cursor.Position.X - 1, Cursor.Position.Y - 1);
}

答案 4 :(得分:0)

(Windows 10 / .Net 5 / C#9.0)

您可以代替伪造活动

通知系统正在使用它,从而防止系统 在应用程序进入睡眠状态或关闭显示器时 正在运行

使用SetThreadExecutionState,如PInvoke.net所述:

using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace VanityApp
{
    internal static class Program
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern ExecutionState SetThreadExecutionState(ExecutionState esFlags);

        [Flags]
        private enum ExecutionState : uint
        {
            ES_AWAYMODE_REQUIRED = 0x00000040,
            ES_CONTINUOUS = 0x80000000,
            ES_DISPLAY_REQUIRED = 0x00000002,
            ES_SYSTEM_REQUIRED = 0x00000001
        }

        private static void Main()
        {
            using AutoResetEvent autoResetEvent = new AutoResetEvent(false);
            using Timer timer = new Timer(state => SetThreadExecutionState(ExecutionState.ES_AWAYMODE_REQUIRED | ExecutionState.ES_CONTINUOUS | ExecutionState.ES_DISPLAY_REQUIRED | ExecutionState.ES_SYSTEM_REQUIRED), autoResetEvent, 0, -1);
            autoResetEvent.WaitOne();
        }
    }
}

计时器是一个System.Threading.Timer,具有方便的构造函数,并且它使用AutoResetEvent.WaitOne()来避免立即退出。

答案 5 :(得分:0)

Raf 为 Win10 世界的问题提供了优雅的答案,但不幸的是,他的 autoResetEvent.WaitOne() 指令阻塞了线程,因此它必须在自己的单独线程中。

对我有用的东西实际上可以在主线程中运行,代码不必放在 Main() 方法中,您实际上可以有一个按钮来启用此功能,一个按钮可以禁用它。

首先,您当然需要定义执行状态标志:

[Flags]
private enum ExecutionState : uint // options to control monitor behavior
{
  ES_AWAYMODE_REQUIRED = 0x00000040, // prevent idle-to-sleep
  ES_CONTINUOUS = 0x80000000, // allow monitor power down
  ES_DISPLAY_REQUIRED = 0x00000002, // prevent monitor power down
  ES_SYSTEM_REQUIRED = 0x00000001 // keep system awake
}

现在,只要您想让系统保持唤醒状态并阻止显示器关闭或空闲进入睡眠状态,您只需执行一个命令:

SetThreadExecutionState(ExecutionState.ES_AWAYMODE_REQUIRED | ExecutionState.ES_CONTINUOUS | ExecutionState.ES_DISPLAY_REQUIRED | ExecutionState.ES_SYSTEM_REQUIRED);

然后,如果您想撤消此操作并将系统返回到其原始执行状态,只需发出以下命令:

SetThreadExecutionState(ExecutionState.ES_CONTINUOUS);

请记住,每个命令都会返回之前的执行状态,这意味着,当您第一次更改此状态时,您可以在本地缓存返回值,并在您想要恢复之前的状态时使用它。