3

コントロール上で、左、右、および両方の3つのマウスアクションが必要です。

私は左と右を持っていて、現在3番目に真ん中のボタンを使用していますが、ユーザーが真ん中のボタンのないマウスを持っている状況で、左と右のボタンを一緒に押す方法を知りたいです。これは、カスタムコントロールのOnMouseDownメソッドで処理されます。

更新 提案された回答を確認した後、私が行おうとしていたのは、MouseDownイベント(実際にはコントロールのOnMouseDownメソッド)でマウスクリックに対してアクションを実行することであったことを明確にする必要があります。マウスの左ボタンと右ボタンの両方がクリックされると(ボタンごとに1つ)、. NETは常に2つのMouseDownイベントを発生させるように見えるため、これを行う唯一の方法は、低レベルのウィンドウメッセージを実行することだと思います。管理またはMouseDown後のアクションのある種の遅延実行を実装します。結局、マウスの中ボタンを使用する方がはるかに簡単です。

これで、アクションがMouseUpで行われた場合、Garyまたはnosの提案がうまく機能します。

この問題に関するさらなる洞察をいただければ幸いです。ありがとう!

4

6 に答える 6

2

私は個人的にMouseUpMouseDownイベントを使用して、それを処理し、相互運用を回避するためのよりクリーンな方法を使用します。基本的に、このコードは静的クラスを使用して2つのボタンのステータスを保持し、両方が実際にダウンしているかどうかを判断できることを確認します。

using System.Windows.Forms;

namespace WindowsFormsApplication1
{

    public static class MouseButtonStatus
    {
        static bool RightButton;
        static bool LeftButton;

        public static bool RightButtonPressed
        {
            get
            {
                return RightButton;
            }
            set
            {
                RightButton = value;
            }
        }

        public static bool LeftButtonPressed
        {
            get
            {
                return LeftButton;
            }
            set
            {
                LeftButton = value;
            }
        }


    }


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void HandleButtons(bool LeftPressed, bool RightPressed)
        {
            if(LeftPressed && RightPressed)
            {
                //BOTH ARE PRESSED
            }
            else if(LeftPressed)
            {
                //LEFT IS PRESSED
            }
            else if(RightPressed)
            {
                //RIGHT IS PRESSED
            }
            else
            {
                //NONE ARE PRESSED
            }
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            if(e.Button == MouseButtons.Left)
            {
                MouseButtonStatus.LeftButtonPressed = true;
            }
            if(e.Button == MouseButtons.Right)
            {
                MouseButtonStatus.RightButtonPressed = true;
            }

            HandleButtons(MouseButtonStatus.LeftButtonPressed, MouseButtonStatus.RightButtonPressed);
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            if(e.Button == MouseButtons.Left)
            {
                MouseButtonStatus.LeftButtonPressed = false;
            }
            if(e.Button == MouseButtons.Right)
            {
                MouseButtonStatus.RightButtonPressed = false;
            }

            HandleButtons(MouseButtonStatus.LeftButtonPressed, MouseButtonStatus.RightButtonPressed);
        }



    }
}
于 2009-07-25T21:42:20.363 に答える
2

「自分でやる」アプローチは常にあります。

ボタンを押して放した状態を覚えておいてください。OnMouseDownでは、押されたボタンを覚えているだけです。OnMouseUpでは、覚えているボタンを確認し、ボタンの状態をクリアします。

ボタンが離されたときにいくつかのアクションを実行しないようにするには、いくつかのロジックが必要です。何かのようなもの

MouseButtons buttonPressed;
..

void OnMouseDown(MouseEventArgs e) 
{
   buttonPressed |= e.Button;
}


void OnMouseUp(MouseEventArgs e) 
{
  if(!doneAction) {
    if((buttonPressed & MouseButtons.Right == MouseButtons.Right 
       && buttonPressed & MouseButtons.Left == MouseButtons.Left)
       || buttonPressed & MouseButtons.Middle== MouseButtons.Middle) {
       DoMiddleAction();
       doneAction = true;
    } else if(check Right button , etc.) {
       .... 
    }
  }

  buttonpressed &= ~e.Button;
  if(buttonpressed == None)
      doneAction = false;

}
于 2009-07-25T20:52:02.103 に答える
1

ネイティブの.Net方法があるかどうかはわかりませんが、P / Invokeに満足している場合は、次のようにGetKeyStateまたはGetAsyncKeyStateを使用できます。

[DllImport("user32.dll")]
public static extern short GetKeyState(int nVirtKey);

if (GetKeyState((int)Keys.LButton) < 0 && GetKeyState((int)Keys.RButton) < 0)
{
    // Both buttons are pressed.
}
于 2009-07-25T19:58:38.403 に答える
0

「真ん中」は「左右一緒」と同じではなかったのですか?少なくともそれは私がどこかで覚えていることですが、それは私がスクロールホイールボタンのない2つのボタンマウスを持っていたときのことです...

于 2009-07-25T20:01:20.303 に答える
0

他の回答から学んだことに基づいて、これを機能させることができました。他の誰かがそれを必要とする場合に備えて、私はここに解決策を投稿します。

MouseDownイベント中に呼び出すコンポーネントMouseDownManagerを作成しました。押されたばかりのボタンを追跡し、「両方の」ボタンダウンイベントを発生させるために待機しているボタンを判別し、タイマーを開始してそのボタンを待機します。割り当てられた時間内に正しいボタンが押された場合、MouseDownManagerは適切な「両方」のボタンダウンイベントを発生させます。それ以外の場合は、適切なシングルボタンイベントが発生します。フォームでは、MouseDownManagerのMouseDownイベントを処理して、翻訳されたマウスクリックに対してアクションを実行しています。

これで、このコンポーネントをフォーム/コントロールにドロップするだけで、「両方」のクリックに反応できます。

これを理解するのに助けてくれてありがとう。

/// <summary>
/// Manage mouse down event to enable using both buttons at once.
/// I.e. allowing the pressing of the right and left mouse
/// buttons together.
/// </summary>
public partial class MouseDownManager : Component
{

  /// <summary>
  /// Raised when a mouse down event is triggered by this
  /// component.
  /// </summary>
  public event EventHandler<MouseEventArgs> MouseDown;

  protected virtual void OnMouseDown( MouseEventArgs e )
  {
    if (this.MouseDown != null)
    {
      this.MouseDown( this, e );
    }
  }

  public MouseDownManager()
  { 
    //-- the timer was dropped on the designer, so it
    //   is initialized by InitializeComponent.
    InitializeComponent();
  }

  /// <summary>
  /// Defines the interval that the timer will wait for the other
  /// click, in milliseconds.
  /// </summary>
  public int BothClickInterval
  {
    get
    {
      return this.tmrBothInterval.Interval;
    }
    set
    {
      this.tmrBothInterval.Interval = value;
    }
  }

  private MouseButtons _virtualButton = MouseButtons.Middle;

  /// <summary>
  /// Defines the button that is sent when both buttons are
  /// pressed. This can be either a single button (like a middle
  /// button) or more than one button (like both the left and
  /// right buttons.
  /// </summary>
  public MouseButtons VirtualButton
  {
    get
    {
      return _virtualButton;
    }
    set
    {
      _virtualButton = value;
    }
  }

  private MouseEventArgs _originalArgs;

  /// <summary>
  /// Defines the original mouse event arguments that is associated
  /// with the original press.
  /// </summary>
  private MouseEventArgs OriginalArgs
  {
    get
    {
      return _originalArgs;
    }
    set
    {
      _originalArgs = value;
    }
  }

  private MouseButtons _waitButton = MouseButtons.None;

  /// <summary>
  /// Defines the button that we are waiting on, for there to be a
  /// both button click.
  /// </summary>
  private MouseButtons WaitButton
  {
    get
    {
      return _waitButton;
    }
    set
    {
      _waitButton = value;
    }
  }

  /// <summary>
  /// Manage a mouse button being depressed.
  /// </summary>
  /// <remarks>
  /// This will instigate one of two actions.  If there is no
  /// current wait button, this will set the appropriate wait
  /// button (if the button pressed was the left button, then we
  /// are waiting on the right button) and start a timer. If the
  /// wait button is set, but this isn't that button, then the wait
  /// button is updated and the timer restarted.  Also, this will
  /// trigger the waiting event.  If it is the wait button, then
  /// the appropriate event is raised for a "both" button press.
  /// </remarks>
  public void ManageMouseDown( MouseEventArgs mouseArgs )
  {
    //-- Is the the button we are waiting for?
    if (mouseArgs.Button == this.WaitButton)
    {
      //-- Turn off timer.
      this.ClearTimer();

      //-- Create new mouse event args for our virtual event.
      MouseEventArgs bothArgs = new MouseEventArgs( this.VirtualButton
                                                  , mouseArgs.Clicks
                                                  , mouseArgs.X
                                                  , mouseArgs.Y
                                                  , mouseArgs.Delta );

      //-- Raise the mouse down event.
      this.OnMouseDown( bothArgs );
    }
    else
    {
      //-- Clear timer
      this.ClearTimer();

      //-- If we were waiting for a button, then
      //   fire the event for the original button.
      if (this.WaitButton != MouseButtons.None)
      {
        this.OnMouseDown( this.OriginalArgs );
      }

      //-- Cache the original mouse event args.
      MouseEventArgs newMouseArgs = new MouseEventArgs( mouseArgs.Button
                                                      , mouseArgs.Clicks
                                                      , mouseArgs.X
                                                      , mouseArgs.Y
                                                      , mouseArgs.Delta );
      this.OriginalArgs = newMouseArgs;

      //-- Reset to wait for the appropriate next button.
      switch (mouseArgs.Button)
      {
        case MouseButtons.Left:
          this.WaitButton = MouseButtons.Right;
          break;
        case MouseButtons.Right:
          this.WaitButton = MouseButtons.Left;
          break;
        default:
          this.WaitButton = MouseButtons.None;
          break;
      }

      //-- Start timer
      this.tmrBothInterval.Enabled = true;
    }
  }

  /// <summary>
  /// Raise the event for the button that was pressed initially
  /// and turn off the timer.
  /// </summary>
  private void tmrBothInterval_Tick( object sender, EventArgs e )
  {
    //-- Turn off the timer.
    this.tmrBothInterval.Enabled = false;

    //-- Based on the original button pressed, raise
    //   the appropriate mouse down event.
    this.OnMouseDown( this.OriginalArgs );

    //-- Clear timer.
    this.ClearTimer();
  }

  /// <summary>
  /// Clear the timer and associated variables so we aren't waiting
  /// for the second click.
  /// </summary>
  private void ClearTimer()
  {
    //-- Turn off the timer.
    this.tmrBothInterval.Enabled = false;

    //-- Clear the wait button.
    this.WaitButton = MouseButtons.None;

    //-- Clear the original args
    this.OriginalArgs = null;
  }
}

/// <summary>
/// Just the mouse code from the control needing the functionality.
/// </summary>
public class MyControl: Control
{
  /// <summary>
  /// Handle the mouse down event. This delegates the actual event
  /// to the MouseDownManager, so we can capture the situation
  /// where both buttons are clicked.
  /// </summary>
  protected override void OnMouseDown( MouseEventArgs e )
  {
    this.mdmMain.ManageMouseDown( e );
  }

  /// <summary>
  /// Process the mouse down event.
  /// </summary>
  private void mdmMain_MouseDown( object sender, MouseEventArgs e )
  {
    //-- Get the reported button state.
    MouseButtons mouseButton = e.Button;

    //-- Execute logic based on button pressed, which now can include
    //   both the left and right together if needed....
  }
}
于 2010-04-27T16:50:15.113 に答える
0

簡単でシンプルな答えはここにあります

bool midL,midR;

private void form1_MouseUp(object sender, MouseEventArgs e)
{
    midL = false;
    midR = false;
}
    
private void form1_MouseDown(object sender, MouseEventArgs e)
{
    if (!midL)
        midL = e.Button == MouseButtons.Left;

    if (!MidR)
        midR = e.Button == MouseButtons.Right;

    if (e.Button == MouseButtons.Middle || (midL && midR))
    {
        MessageBox.show("Middle button is pressed")
    }
}
于 2021-02-28T10:58:43.693 に答える