我想有超过一控三个鼠标操作:左,右和两者。
我有左,右,我目前使用的第三中间的按钮,但很好奇我怎么能使用左,按下左右键一起,对于用户有没有中键鼠标的情况。 这将在定制控件的onmousedown事件的方法来处理。
UPDATE审查建议的答复后,我需要澄清的是什么,我试图做的是采取在MouseDown事件上的鼠标点击动作(实际上onmousedown事件控制的方法)。 因为它看起来.NET总会提出两个MouseDown事件中,被点击两个鼠标上的左右键时(每个按钮),我猜这样做,这将是要么做一些低级别的Windows消息的唯一途径管理或实施某种形式的MouseDown之后的动作延迟执行的。 最后,它只是简单的方式使用鼠标中键。
现在,如果动作发生在的MouseUp,然后Gary的或NOS的建议将工作做好。
在这个问题上的任何进一步的见解,将不胜感激。 谢谢!
总是有“自己动手”的方法:
只记得按下按钮和释放状态。 在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;
}
我个人使用MouseUp
和MouseDown
事件更清洁的方式来处理它,避免互操作。 基本上这个代码使用静态类来保存两个按钮,并通过检查可以判断羯羊两种状态实际上下来。
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);
}
}
}
不知道是否有一个本地.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.
}
是不是“中”同为“左,右在一起”? 至少这是我从什么地方还记得,但那是从回来的路上,当我有没有滚轮按钮两粒扣鼠...
根据我从其他的答案了解到,我能得到这个工作。 我张贴在这里的情况下,解决方案的一些人需要它。
我创建了一个组件,MouseDownManager,我MouseDown事件中调用。 它跟踪刚按下按钮,决定了我们是为了有一个“既”按钮按下事件等什么按钮,然后启动一个定时器,以等待按钮。 如果在规定时间内,按下正确的按钮,该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....
}
}