我正在尝试制作一个程序,该程序需要能够以最小的延迟将光标移动到并单击屏幕上的预定义坐标。
我所做的是使用pinvoke从user32.dll访问功能SetCursorPos和mouse_event
但是,当我使用秒表计时这些功能花费的时间时,SetCursorPos约为2毫秒,而mouse_event约为30毫秒或更长时间。我想知道是否可以更快地执行此操作?
有一个用于改进互操作性能的库,称为AdvancedDLSupport。我正在考虑这一点,甚至通过电子邮件将其发送给github存储库的作者,但是在回复中,我被告知,对于我正在做的真正瓶颈,更可能是Windows输入队列本身。
因此,是否有必要将mouse_event置于该队列的顶部并希望在不到一毫秒的时间内执行?我真的不知道这是否有可能,如果可能的话,那么它就没有很好的记录,因为我在网上找不到有关此信息。
我只是一个新手程序员,甚至不知道从哪里开始弄清楚该怎么做,这超出了我的知识范围,而且即使有可能,即使是专业的程序员也可能很困难。任何帮助将不胜感激。
这是我到目前为止的代码(这只是较大程序中的一个类):
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.CompilerServices;
namespace NetMQ_test_project
{
public class AutoClicker
{
//invoking DLLs to have access to GetCursorPos, SetCursorPos, mouse_event
//from windows API
//naming conventions are not standard for C#
[DllImport("user32.dll")]
static extern bool GetCursorPos(out POINT lpPoint);
[DllImport("user32.dll")]
static extern bool SetCursorPos(int x, int y);
[DllImport("user32.dll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
public const int MOUSEEVENTF_LEFTDOWN = 0x02;
public const int MOUSEEVENTF_LEFTUP = 0x04;
private static POINT _buyPos;
private static POINT _sellPos;
public bool Executed = false;
private static POINT SetPos()
{
Console.WriteLine("Move cursor to desired position and press the S key to set. (Don't minimize this window)");
POINT nullPoint = new POINT();
if(Console.ReadKey(true).Key == ConsoleKey.S)
{
GetCursorPos(out POINT point);
return point;
}
else
{
return nullPoint;
}
}
public static void SetBuyPos()
{
Console.WriteLine("Setting Buy Position...");
_buyPos = SetPos();
Console.WriteLine("Buy Pos: {0},{1}", _buyPos.X, _buyPos.Y);
}
public static void SetSellPos()
{
Console.WriteLine("Setting Sell Position...");
_sellPos = SetPos();
Console.WriteLine("Sell Pos: {0},{1}",_sellPos.X,_sellPos.Y);
}
public static void Click()
{
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ClickBuy()
{
var sw = new Stopwatch();
sw.Start();
SetCursorPos(_buyPos.X, _buyPos.Y);
sw.Stop();
sw.Reset();
sw.Start();
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
sw.Stop();
sw.Reset();
//mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
//Click(); changed to be in-line to improve performance. Less elegant but whatever
//Console.WriteLine("Buy Pos: {0},{1}", _buyPos.X, _buyPos.Y);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ClickSell()
{
SetCursorPos(_sellPos.X, _sellPos.Y);
Click();
//Console.WriteLine("Sell Pos: {0},{1}", _sellPos.X, _sellPos.Y);
}
}
}