2012-02-06 3 views
2

Как я упоминал в 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 
+1

что здесь не работает? – Tigran

+0

Событие двойного щелчка не происходит вообще! – ykombinator

+0

Я бы предложил вам использовать [Reactive Extensions] (http://stackoverflow.com/questions/5228364/reactive-framework-doubleclick), чтобы это сделать. –

ответ

1

Я надеюсь, что это не плохо этикета, чтобы обеспечить два ответа, однако это очень отличается от моего предыдущего ответа я чувствовал редактирования для улучшения WASN Правильно.

По внешнему виду у вас есть только обработчик событий в форме, как только вы наведите указатель мыши на элемент управления формы, который вызовет ваше событие 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

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

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

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 
} 
0

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

Это сказанное, однако, я думаю, что ответ на наш вопрос здесь: SendInput doesn't perform click mouse button unless I move cursor

0

Основная идея: Я использую 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; 
    } 
} 
Смежные вопросы