Fajer Albloushi
Fajer Albloushi

Reputation: 13

Moving the mouse according to the given coordinates

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);
                }
            }
        }'

Upvotes: 1

Views: 737

Answers (1)

TaW
TaW

Reputation: 54453

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:

enter image description here

Upvotes: 1

Related Questions