【问题标题】:Implementing double click event using timer使用定时器实现双击事件
【发布时间】:2012-02-06 12:47:51
【问题描述】:

正如我在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

【问题讨论】:

  • 我建议你使用Reactive Extensions 去那个。
  • 双击事件根本没有发生!
  • @ykombinator:你为什么不使用MouseEnter事件?
  • @Tigran 将此代码视为一些 RSI 自动点击器应用程序,因此使用了 SendInput API 方法,以便所有正在运行的程序都可以使用该功能。

标签: c# .net winforms mouseevent emgucv


【解决方案1】:

乍一看,如果您期望双击,那么您只需要单击一次。

向下然后向上是单击鼠标,不是吗?

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
}

【讨论】:

    【解决方案2】:

    我希望提供两个答案是一种不错的礼仪,但这与我之前的答案有很大不同,我觉得为改进而编辑是不正确的。

    从外观上看,表单上只有一个事件处理程序,一旦您将鼠标悬停在表单上的控件上,该控件将触发表单的 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();
        }
    }
    

    【讨论】:

      【解决方案3】:

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

      话虽如此,我认为我们的问题的答案在这里:SendInput doesn't perform click mouse button unless I move cursor

      【讨论】:

        【解决方案4】:

        基本思路: 我使用 MouseAdapter,这样我就不必在阳光下覆盖所有东西。

        我的 MouseAdapter 对象有一个 MouseTimer,它扩展了一个 swing Timer, 和一个带有重写匿名 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();
        
                   }
             }
         };
        

        类 MouseTimer 是类 Timer 的子类。当 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;
             }
        }
        

        【讨论】:

          猜你喜欢
          • 2012-02-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多