タイマを使用してダブルクリックイベントを実装する

こちらの質問に記載されているように、私は自分のアプリに機能を実装しようとしています。カーソルを何点か押して(例えば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
2
@TigranはこのコードをいくつかのRSIオートクリッカーアプリで見ているので、実行中のすべてのプログラムで機能が利用できるようにSendInput APIメソッドが使用されています。
追加された 著者 Jeremy Thompson,
何がここで動作しないのですか?
追加された 著者 Tigran,
@ykombinator: MouseEnter イベントを使用してみませんか?
追加された 著者 Tigran,
ダブルクリックイベントはまったく発生しません!
追加された 著者 ykombinator,
リアクティブエクステンションを使用することをお勧めします。
追加された 著者 Alexey Raga,

4 答え

一見すると、あなたのダブルクリックを期待している場合は、シングルクリックだけをしています。

マウスを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
追加された

私はそれが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();
    }
}
1
追加された

このコードをSendInputへの単一の呼び出しとして、すべてのマウスダウンとアップを1つの配列に渡す方がよいでしょう。これを行うと、SendInputはシーケンス間に他のキーが入らないことを保証します。たとえば、ユーザーがAlt + Nキーを理論的に保持していると、それが侵入する可能性があります。オートクリッカーを変更して「はい」をクリックすると、代わりに「いいえ」(Alt + Nキーを押したまま)がトリガーされます。

That being said however, I think the answer to our question is here: SendInput doesn't perform click mouse button unless I move cursor

0
追加された

Basic Idea: I use MouseAdapter so that I don't have to override everything under the sun.

私のMouseAdapterオブジェクトには、スイングタイマーを拡張するMouseTimerがあり、 オーバーライドされた匿名の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クラスの子です。遅延後にタイマーが起動すると、そのタイムパン内にシングルクリックまたはダブルクリックがあったかどうかを確認するチェックがあります。

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
追加された