使用计时器实现双击事件

时间:2012-02-06 12:47:51

标签: c# .net winforms mouseevent emgucv

正如我在this问题中提到的,我正在尝试在我的应用中实现一项功能,即将光标放在某个点上一段时间(比如3-5秒)会触发双击事件。基于该线程中提供的答案,我写了以下内容。此代码未按预期工作。有人可以帮忙吗?

    #region Timer Mouse Double Click event

    timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);

    //Here, the timer for Timer click event will start when mouse hovers over an area
    private void form_MouseHover(object sender, System.EventArgs e)
    {
        timer.Start();
    }

    private void form_MouseLeave(object sender, System.EventArgs e)
    {
        timer.Stop();
    }

    void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        timer.Stop();
        DoubleClickEvent();
    }

    //This method allows the user to click a file/folder by hovering/keeping still the mouse for specified time
    void DoubleClickEvent()
    {

        DoClickMouse(0x2);      // Left mouse button down
        DoClickMouse(0x4);      // Left mouse button up
    }

    static void DoClickMouse(int mouseButton)
    {
        var input = new INPUT()
        {
            dwType = 0, // Mouse input
            mi = new MOUSEINPUT() { dwFlags = mouseButton }
        };

        if (SendInput(1, input, Marshal.SizeOf(input)) == 0)
        {
            throw new Exception();
        }
    }
    [StructLayout(LayoutKind.Sequential)]
    struct MOUSEINPUT
    {
        int dx;
        int dy;
        int mouseData;
        public int dwFlags;
        int time;
        IntPtr dwExtraInfo;
    }
    struct INPUT
    {
        public uint dwType;
        public MOUSEINPUT mi;
    }
    [DllImport("user32.dll", SetLastError = true)]
    static extern uint SendInput(uint cInputs, INPUT input, int size);

    #endregion

4 个答案:

答案 0 :(得分:2)

乍一看,如果您希望双击,只需点击一下即可。

向下然后向上是一次鼠标点击,你不应该这样做。

void DoubleClickEvent()
{
    DoClickMouse(0x2);      // Left mouse button down
    DoClickMouse(0x4);      // Left mouse button up        
    DoClickMouse(0x2);      // Left mouse button down
    DoClickMouse(0x4);      // Left mouse button up
}

答案 1 :(得分:1)

我希望提供两个答案是不错的礼仪,但这与我以前的答案非常不同,我觉得编辑改进不正确。

通过它的外观,只有将鼠标悬停在表单上的控件上才会触发表单的MouseLeave事件,表单上只有一个事件处理程序。

你需要的是为你的表单上的每个控件添加一个事件处理程序,像这样应该这样做。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

        this.MouseHover += new EventHandler(MouseHoverEvent);
        this.MouseLeave +=new EventHandler(MouseLeaveEvent);
        timer1.Tick += new EventHandler(timer1_Tick);

        foreach (Control item in this.Controls)
        {
            item.MouseHover += new EventHandler(MouseHoverEvent);
            item.MouseLeave += new EventHandler(MouseLeaveEvent);
        }

    }

    void timer1_Tick(object sender, EventArgs e)
    {
        timer1.Stop();
        DoubleClickEvent();
    }

    void MouseLeaveEvent(object sender, EventArgs e)
    {
        timer1.Stop();
    }

    void MouseHoverEvent(object sender, EventArgs e)
    {
        timer1.Start();
    }
}

答案 2 :(得分:0)

最好将此代码编写为SendInput的单个调用,将所有鼠标按下并在一个数组中传递。如果这样做,SendInput保证序列之间没有其他键。例如,如果用户理论上持有Alt + N键,它可以潜入 - 并更改自动点击器,单击是以改为触发否(使用Alt + N键)。

尽管如此,我认为我们问题的答案在于:SendInput doesn't perform click mouse button unless I move cursor

答案 3 :(得分:0)

基本理念: 我使用MouseAdapter,所以我不必覆盖太阳下的所有东西。

我的MouseAdapter对象有一个MouseTimer,它扩展了一个swing计时器, 和一个带有重写的匿名actionPerformed方法的ActionListener。

我可能已经过度思考/或在思考何时启动和停止计时器对象。 基本上它所做的只是单击或双击时打印出来。

package mouseUtils;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Timer;

/**
 *
 * @author jcpartri
 */
public class MyMouseAdapter extends MouseAdapter{
     private Integer mouseDoubleClickInterval = (int)     
     Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
     private MouseEvent event = null;
     private ActionListener taskPerformer = new ActionListener(){
      @Override
      public void actionPerformed(ActionEvent e){
           if(event.getClickCount() == 2){
                //mouseDoubleClicked(event);
                mouseTimer.stop();
           }
           if(event.getClickCount() == 1){
                //mouseSingleClicked(event);
                mouseTimer.stop();

           }
     }
 };

Class MouseTimer类是Timer类的子类。当计时器在延迟后触发时,会检查该时间段内是否有单击或双击。

private MouseTimer mouseTimer = new  

MouseTimer(getMouseDoubleClickInterval(),taskPerformer);

 //The DebugClock helps me to see how long a process that I have programmed takes from 
start to finish.
     private DebugClock clock = new DebugClock();

 //Constructors
 public MyMouseAdapter(){
      super();
 }


@Override
public void mouseClicked(MouseEvent e){ 
     event = e;
     if(e.getClickCount() == 1){
          mouseTimer.setInitialDelay(mouseDoubleClickInterval);
          mouseTimer.start();
     }
     mouseTimer.setNumOfClicks();
}

public void mouseSingleClicked(MouseEvent e){
     p("Mouse was SingleClicked!!!\n");
}
public void mouseDoubleClicked(MouseEvent e){
     p("Mouse was DoubleClicked!!!\n");
}
@Override
public void mouseMoved(MouseEvent e){
     event = e;
     mouseTimer.resetNumOfClicks();
     mouseTimer.stop();
}

//Setters and Getters for MouseAdapter
public Integer getMouseDoubleClickInterval(){
      return this.mouseDoubleClickInterval;
}



    //Timer Classes
    private class MouseTimer extends Timer{

     //Constructors
     public MouseTimer(int delay, ActionListener taskPerformer){
          super(delay,taskPerformer);
     }

     //Instance variables
     private int numOfClicks = 0;


      //Setters and Getters
      public int getNumOfClicks(){
           return this.numOfClicks;
      }
      public void setNumOfClicks(){
           this.numOfClicks++;
      }
      public void resetNumOfClicks(){
           this.numOfClicks = 0;
      }
    }
    //Basic Printing Classes
    private void p(String message){
     System.out.print(message);
    }
}

class DebugClock{
     private long startTime = 0;
     private long endTime = 0;

     //Setters and Getters
     public long getStartTime(){
          return this.startTime;
     }
     public void setStartTime(long start){
          this.startTime = start;
     }
     public long getEndTime(){
          return this.endTime;
     }
     public void setEndTime(long end){
          this.endTime = end;
     }

     //Constructors
     public DebugClock(){

     }

     //Methods
     public float getTimeInMilliSeconds(){
          float seconds = (this.endTime - this.startTime);
          return seconds;
     }
}