代码之家  ›  专栏  ›  技术社区  ›  Fajer Albloushi

根据给定坐标移动鼠标

  •  1
  • Fajer Albloushi  · 技术社区  · 7 年前

    我想要的是,在记录鼠标移动并保存坐标/索引/位置后,我必须加载鼠标坐标并使鼠标根据加载的坐标移动 我没有代码给你看,因为我在这一点上卡住了

         ' 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);
                    }
                }
            }'
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   TaW    7 年前

    这是一个快速而肮脏的解决方案:

    让我们从几个变量开始:

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

    最后是重播按钮;它使用索引在新的 计时器。打上钩 代码,但使用相同的计时器:

    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协调人。它会在固定的时间间隔内播放,因此播放看起来与原来的动作非常相似;事实上,很难区分,我添加了一个间隔较长的slowmo按钮来演示。。(但gif太大了)

    • 该代码将在屏幕坐标中记录鼠标位置,并应在任何地方捕获鼠标位置,而不仅仅是在应用程序内部。查看VS如何激活代码loupe!

    • 它不会记录任何其他鼠标事件,如向上、向下、单击、双击或滚轮。对于那些你需要一个全局鼠标钩子来捕获和一些外部调用来重播。

    • 为了包含其他鼠标事件,您还需要一个不同的扩展数据结构;您还必须从计时器驱动的模型转向鼠标事件驱动的模型。

    • 该示例使用按钮启动和停止。当然,这些按钮之间的移动也会包含在记录的位置列表中。相反,可以使用定时启动,它将在几秒钟后开始录制,并在几秒钟不活动后停止录制。。

    有多种方法可以保存和加载点;最简单的方法是序列化为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相对稳定。

    以下是一个短片:

    enter image description here