How to subscribe to double clicks?

2019-05-26 23:01发布

问题:

I'm trying to find a way to subscribe to double-click event in XNA, and googling gets me winforms related stuff, which isn't the case, I can't use that.

Using Timespan and guessing how long the timeout for double click is on a PC is not very reliable.

Default XNA input system also has this little flaw: sometimes a key press or a mouse click gets lost between updates and it would ruin double-click reliability in high load moments of the game.

How do I subscribe to double-click events in .net?


The "without using Control class events" was removed, since there actually is a way to use that class (see my answer).

回答1:

You can create your own double-click checker as described in this post.

double ClickTimer;
const double TimerDelay = 500;

public override void Update(GameTime gameTime)
{
     ClickTimer += gameTime.ElapsedGameTime.TotalMilliseconds;
     if(Mouse.GetState().LeftButton == ButtonState.Pressed)
     {
          if(ClickTimer < TimerDelay)
              //this is a double click
          else
              //this is a normal click

          ClickTimer = 0;
     }
}

In that code, 500 is set as the maximum time in milliseconds a user has to double click. To get the milliseconds the user has set as their system's maximum double click time (instead of just setting it to an arbitrary value of 500), you can either import the Windows.Forms assembly and read the SystemInformation.DoubleClickTime property or, if you don't want to import the assembly, you can P/Invoke the GetDoubleClickTime method.

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int GetDoubleClickTime(); 

So adding the above method to the XNA code, you can get the user's default double click time like this

const double TimerDelay = (double)GetDoubleClickTime();


回答2:

I just came up with this:

using wf = System.Windows.Forms;

wf.Form form = (wf.Form)wf.Control.FromHandle(this.Window.Handle);
form.MouseDoubleClick += new wf.MouseEventHandler(form_MouseDoubleClick);

So there really is a way to do this in XNA using Control class :)