所以我制作了一个程序,用来跟踪游戏中的鼠标动作,叫做铁锈。我制作了这个程序来跟踪枪械上的喷雾图案等等。我制作了这个程序,除了它只跟踪屏幕上的位置,而不是实际的移动。在像铁锈这样的游戏中,鼠标总是以中心为中心,所以它是无用的。我到处找,我能想到的每一个搜索标题都找不到任何东西。跟踪返回X和Y坐标的鼠标运动的最佳方法是什么?
TL:I博士做了一个程序,它的工作方式,但错误的方式,什么是最好的方式跟踪鼠标运动返回X和Y坐标?
如果需要的话,下面是代码:
using System;
using Timer = System.Timers.Timer;
using System.Timers;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;
using Gma.System.MouseKeyHook;
using System.IO;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace MouseTrackerConsole
{
class Program
{
private static List<Coords> QuickCoords = new List<Coords>();
private static int fileNumber = 0;
private static Rectangle screenResolution = Screen.PrimaryScreen.Bounds;
private static IKeyboardMouseEvents HookEvents = null;
private static Timer loopTimer;
[STAThread]
static void Main(string[] args)
{
DirectoryInfo di = new DirectoryInfo("Spray");
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
loopTimer = new Timer();
loopTimer.Interval = 100;
loopTimer.Enabled = false;
loopTimer.Elapsed += loopTimerEvent;
loopTimer.AutoReset = true;
if(!Directory.Exists("Spray"))
{
Directory.CreateDirectory("Spray");
}
Hook.GlobalEvents().MouseDown += async (sender, e) =>
{
if (e.Button == MouseButtons.Left)
{
Thread.Sleep(100);
loopTimer.Enabled = true;
}
};
Hook.GlobalEvents().MouseUp += async (sender, e) =>
{
if (e.Button == MouseButtons.Left)
{
loopTimer.Enabled = false;
if (QuickCoords.Count == 0)
{
}
else
{
using (StreamWriter file = File.CreateText($@"Spray\Spray{fileNumber}.akspray"))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, QuickCoords);
}
QuickCoords.Clear();
fileNumber += 1;
Console.WriteLine(fileNumber);
}
}
};
try
{
Application.Run(new ApplicationContext());
}
catch (AccessViolationException)
{
Environment.Exit(0);
}
}
private static void loopTimerEvent(Object source, ElapsedEventArgs e)
{
Console.WriteLine("x: " + Cursor.Position.X + " y: " + Cursor.Position.Y);
QuickCoords.Add(new Coords { X = Cursor.Position.X.ToString(), Y = Cursor.Position.Y.ToString() });
}
}
internal class Coords
{
public string X { get; set; }
public string Y { get; set; }
}
}
先谢谢你
发布于 2021-02-17 10:08:19
使用Pinvoke是可能的。这里的解决方案是一个开始,但前台应用程序仍可能捕获它,并且从未向您的应用程序报告。
如果是这样的话,您可以使用另一个winapi调用,SetWindowsHooksEx,如下所示:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);
您仍然需要做一些腿工作来设置winapi结构和钩子的回调,但是有一个很好的例子说明了如何在这里设置它:在C#和P/Invoke中使用windows钩子
重要的部分是:
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
internal delegate IntPtr HookProc(int nCode, UIntPtr wParam, IntPtr lParam);
和
[StructLayout(LayoutKind.Sequential)]
internal struct MouseLowLevelHookStruct
{
public Point pt;
public int mouseData;
public int flags;
public int time;
public IntPtr dwExtraInfo;
}
然后,问题是使用适当的回调设置钩子,并将lParam封送到MouseLowLevelHookStruct。
编辑:我看了一下您正在使用的MouseKeyHook nuget包,它似乎在幕后调用我前面提到的winapi方法。我无法让它在控制台应用程序中正常工作,但是在一个winform应用程序中,下面的鼠标动作都很好:
Gma.System.MouseKeyHook.Hook.GlobalEvents().MouseMoveExt += Form1_MouseMoveExt;
它甚至报告了试图将鼠标光标从屏幕上移出屏幕的负数,因此它很可能能够报告来自一个应用程序的事件,该应用程序使鼠标无法被捕获。除非您有一个非常好的理由来坚持使用控制台应用程序,否则只需切换到winforms并使用该事件处理程序就更容易了。
https://stackoverflow.com/questions/66235128
复制相似问题