根据给定的坐标移动鼠标 [英] Moving the mouse according to the given coordinates
问题描述
我想要的是,在记录鼠标移动并保存坐标/索引/位置之后,我将不得不加载鼠标坐标并使鼠标根据加载的坐标进行移动 我没有代码向您展示,因为此时此刻被困住了
' private void button3_Click_1(object sender, EventArgs e)
{
StreamWriter writer;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
string[] cvsArray = new string[10000];
saveFileDialog1.Filter = "All files (*.All)|*.All|All files (*.*)|*.*";
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
writer = File.CreateText(saveFileDialog1.FileName);
// if ((myStream = saveFileDialog1.OpenFile()) != null)
//{
for (int i = 0; i < cvsArray.Length; i++)
{
string text = richTextBox1.Text;
writer.WriteLine(text);
}
// Code to write the stream goes here.
writer.Close();
//}
}
}
private void button11_Click(object sender, EventArgs e)
{
StreamReader reader;
string Line;
string[] cvsArray;
string position;
//set the filter to dialog control
openFileDialog1.Filter = FILTER;
//check if the user selected the right file
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
//open the selected file
reader = File.OpenText(openFileDialog1.FileName);
//Read the entireline form the file
Line = reader.ReadLine();
//read while it is still not the end of the file
while (!reader.EndOfStream)
{
Line = reader.ReadLine();
//Splite the line using array
cvsArray = Line.Split(':');
position = cvsArray[0];
//position = cvsArray[1];
listBox1.Items.Add(position);
}
}
}'
这是一个快速而肮脏的解决方案:
让我们从几个变量开始:
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比较稳定.
这是一个简短的剪辑:
what I want is, after recording the mouse movement and saving the coordinates/ indexes/ position, I will have to load the mouse coordinates and make the mouse move according to the loaded coordinates i don't have code to show you because am stuck at this point
' private void button3_Click_1(object sender, EventArgs e)
{
StreamWriter writer;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
string[] cvsArray = new string[10000];
saveFileDialog1.Filter = "All files (*.All)|*.All|All files (*.*)|*.*";
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
writer = File.CreateText(saveFileDialog1.FileName);
// if ((myStream = saveFileDialog1.OpenFile()) != null)
//{
for (int i = 0; i < cvsArray.Length; i++)
{
string text = richTextBox1.Text;
writer.WriteLine(text);
}
// Code to write the stream goes here.
writer.Close();
//}
}
}
private void button11_Click(object sender, EventArgs e)
{
StreamReader reader;
string Line;
string[] cvsArray;
string position;
//set the filter to dialog control
openFileDialog1.Filter = FILTER;
//check if the user selected the right file
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
//open the selected file
reader = File.OpenText(openFileDialog1.FileName);
//Read the entireline form the file
Line = reader.ReadLine();
//read while it is still not the end of the file
while (!reader.EndOfStream)
{
Line = reader.ReadLine();
//Splite the line using array
cvsArray = Line.Split(':');
position = cvsArray[0];
//position = cvsArray[1];
listBox1.Items.Add(position);
}
}
}'
This is a quick and rather dirty solution:
Let's start with a few varibles:
List<Point> points = null;
Timer tt = null;
int index = 0;
Now a button to start the recoding; it initializes a List<Point>
to collect the positions and creates and starts a Timer
along with lambda
code to do the recoding in the Timer.Tick
event:
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);
};
}
Next a button to stop recording:
private void btn_Stop_Click(object sender, EventArgs e)
{
if (tt!=null) tt.Stop();
}
Finally the replay button; it uses an index to loop over the the points collection in a new Timer.Tick
code but using the same timer:
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();
}
A few notes:
As asked in the question this will record and reply the Mmouse coodinates. It will do so in fixed intervals, so playback will look very similar to the original movements; in fact it is so hard to tell apart that I added a slowmo button with a longer interval to demonstrate.. (But the gif got too large)
The code will record the mouse positions in screen coordinates and should capture them wherever it goes, not only inside your application. See how VS is activating the code loupe!
It will not record any other mouse events, like up, down, click, doubleclick or wheel. For those you would need a global mouse hook for capturing and some external calls for replaying.
For including other mouse events you would also need a different and extended data structure; and you would also have to go from a timer-driven model to a mouse event driven one.
The example uses buttons to start and stop. Of course the movenments to and from those buttons get included in the recorded list of positions. Instead one could use a timed start, which would start recording after a few seconds and stop recording after a few seconds of inactivity..
There are various ways you can save and load the points; the simplest one is to serialize to xml; using a string path = @"..."
it could look as simple as this:
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();
}
}
Other ways would be using a binary formatter or a custom conversion routine. Xml is relatively stable.
Here is a short clip:
这篇关于根据给定的坐标移动鼠标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!