Реализация события двойного щелчка с использованием таймера - PullRequest
2 голосов
/ 06 февраля 2012

Как я уже упоминал в этом вопросе, я пытаюсь реализовать в своем приложении функцию, посредством которой наведение курсора на некоторую точку на некоторое время (скажем 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 ]

2 голосов
/ 06 февраля 2012

На первый взгляд, если вы ожидаете двойной щелчок, вы делаете только один щелчок.

Вниз, затем вверх - один щелчок мыши, не так ли?

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 голос
/ 13 февраля 2012

Надеюсь, что не так уж и плохо дать два ответа, но это сильно отличается от моего предыдущего ответа, который, как мне показалось, не корректировался для улучшения.

Похоже, у вас есть только обработчик событий в форме, когда вы наводите курсор мыши на элемент управления в вашей форме, который вызовет событие 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();
    }
}
0 голосов
/ 06 июля 2013

Основная идея: Я использую MouseAdapter, чтобы мне не пришлось переопределять все под солнцем.

мой объект MouseAdapter имеет MouseTimer, который расширяет таймер поворота, и ActionListener с переопределенным анонимным методом actionPerformed.

Возможно, я задумался над тем, когда запускать и останавливать объект таймера. По сути, все, что он делает, это распечатывает, когда он щелкается одним щелчком мыши или когда щелкают дважды.

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. Когда таймер срабатывает после задержки, выполняется проверка, был ли один или два щелчка за этот промежуток времени.

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;
     }
}
0 голосов
/ 07 февраля 2012

Может быть, лучше написать этот код в виде одного вызова SendInput, передавая все взлеты и падения мыши в одном массиве.Если вы сделаете это, SendInput гарантирует, что никакие другие ключи не попадут между последовательностями.Например, если у пользователя теоретически удерживаются клавиши Alt + N, он может проникнуть внутрь и изменить автоматический щелчок мышью, нажав «Да», чтобы вместо этого активировать «Нет» (удерживая клавиши «Alt + N»).

При этомтем не менее, я думаю, что ответ на наш вопрос здесь: SendInput не выполняет щелчок мышью, пока я не перемещаю курсор

...