Это быстрое и довольно грязное решение:
Давайте начнем с нескольких переменных:
List<Point> points = null;
Timer tt = null;
int index = 0;
Теперь кнопка для начала записи; он инициализирует List<Point>
для сбора позиций и создает и запускает Timer
вместе с lambda
кодом для перекодирования в событии Timer.Tick
:
private void btn_Record_Click(object sender, EventArgs e)
{
points = new List<Point>();
index = 0;
tt = new Timer()
{ Interval = 50, Enabled = true };
tt.Tick += (ss, ee) =>
{
if (!points.Any() || points.Last() != Control.MousePosition)
points.Add(Control.MousePosition);
};
}
Следующая кнопка для остановки записи:
private void btn_Stop_Click(object sender, EventArgs e)
{
if (tt!=null) tt.Stop();
}
Наконец кнопка воспроизведения; он использует индекс для циклического перебора набора точек в новом коде Timer.Tick
, но с использованием того же таймера:
private void btn_Replay_Click(object sender, EventArgs e)
{
index = 0;
tt = new Timer() { Interval = 50, Enabled = true };
tt.Tick += (ss, ee) =>
{
if (index < points.Count)
{ System.Windows.Forms.Cursor.Position = points[index++]; }
else tt.Stop();
}
Несколько заметок:
Как и было задано в этом вопросе, это запишет и ответит каудинатам Mmouse. Это будет происходить через фиксированные интервалы, поэтому воспроизведение будет выглядеть очень похоже на исходные движения; на самом деле так сложно отличить друг от друга, что я добавил медленную кнопку с более длинным интервалом, чтобы продемонстрировать .. (Но GIF стал слишком большим)
Код будет записывать позиции мыши в координатах экрана и должен фиксировать их везде, где бы они ни находились, а не только внутри вашего приложения. Посмотрите, как VS активирует код лупы!
Он не будет записывать какие-либо другие события мыши, например, вверх, вниз, щелчок, двойной щелчок или колесико. Для них вам понадобится глобальный хук мыши для захвата и некоторые внешние вызовы для воспроизведения.
Для включения других событий мыши вам также потребуется другая и расширенная структура данных; и вам также придется перейти от модели, управляемой таймером, к модели, управляемой событиями мыши.
В примере используются кнопки для запуска и остановки. Конечно, движения к и от этих кнопок включаются в записанный список позиций. Вместо этого можно использовать синхронизированный запуск, который начнет запись через несколько секунд и прекратит запись через несколько секунд бездействия.
Существуют различные способы сохранения и загрузки точек; самый простой - это сериализация в xml; используя string path = @"..."
это может выглядеть так просто:
private void btn_save_Click(object sender, EventArgs e)
{
if (points == null) points = new List<Point>();
XmlSerializer xs = new XmlSerializer((points).GetType());
using (TextReader tr = new StreamReader(path))
{
points = (List<Point>)xs.Deserialize(tr);
tr.Close();
}
}
private void btn_load_Click(object sender, EventArgs e)
{
XmlSerializer xs = new XmlSerializer((points).GetType());
using (TextWriter tw = new StreamWriter(path))
{
xs.Serialize(tw, points);
tw.Close();
}
}
Другими способами было бы использование двоичного форматера или пользовательской процедуры преобразования. XML относительно стабилен.
Вот короткий клип: