通过方向防止鼠标移动

时间:2012-07-21 21:07:24

标签: c# winforms

如果我的某些情况发生,我正在寻找一种防止鼠标移动的方法。

请注意,我不想在OnMouseMove事件上工作,因为对我来说太迟了。

我需要类似Cursor.Clip属性的东西。有没有能够禁用鼠标移动方向的API?一种ApiMouse.DisableMovement(Directio.Up | Direction.Down | Direction.Left | Direction.Right)?

2 个答案:

答案 0 :(得分:1)

如果您不喜欢覆盖OnMouseMove,那么您可能希望覆盖WndProc。 “抓住”窗口鼠标移动消息并根据您的规则丢弃它们。这是我所知道的最快的方式。

private const int WM_MOUSEMOVE = 0x0200;
private const int MK_LBUTTON = 0x0001;
protected override void WndProc(ref Messsage msg)
{
    switch(msg.Msg)
    {
      case WM_MOUSEMOVE: // If you don't want the cursor to move, prevent the code from reaching the call to base.WndProc
              switch (msg.WParam.ToInt32())
              {
                    case MK_LBUTTON: // the left button was clicked
                         break; 
              }
              break;
    }
    base.WndProc(ref msg);
}

使用LParamWParam为您提供有关鼠标当前状态的更多信息。检查this以便更好地理解。

修改 要获取鼠标的坐标,请检查此question.。它表明:

int x = msg.LParam.ToInt32() & 0x0000FFFF;
int y = (int)((msg.LParam.ToInt32() & 0xFFFF0000) >> 16)
Point pos = new Point(x, y);

答案 1 :(得分:1)

在对上一个答案的评论中,您可以参考上一个问题"Form move inside client desktop area"。接受的答案中的代码可以防止窗口移动到桌面之外。现在,您希望在用户拖动光标时将光标“固定”到窗口。因此,如果窗口不能进一步移动,光标也不应该更进一步。

如果我对您的问题的理解是正确的,您应该处理WM_NCLBUTTONDOWN消息以计算鼠标移动的限制。然后,您可以使用Cursor.Clip来应用这些限制。

但是,如果在WM_NCLBUTTONDOWN消息中应用剪辑矩形,则会立即将其删除。如果您在WM_MOVING消息中应用它,则在拖动结束时将自动删除它。

这也是上述问题的解决方案:如果鼠标只能在用户拖动窗口时在计算的矩形中移动,那么窗口本身只能在允许的区域中移动。

public const int WM_MOVING = 0x0216;
public const int WM_NCLBUTTONDOWN = 0x00A1;
public const int HT_CAPTION = 0x0002;

private Rectangle _cursorClip = Rectangle.Empty;

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case WM_NCLBUTTONDOWN:
            if (m.WParam.ToInt32() == HT_CAPTION)
            {
                Point location = Cursor.Position;
                Rectangle screenBounds = Screen.PrimaryScreen.Bounds;
                Rectangle formBounds = Bounds;

                _cursorClip = Rectangle.FromLTRB(location.X + screenBounds.Left - formBounds.Left,
                                                 location.Y + screenBounds.Top - formBounds.Top,
                                                 location.X + screenBounds.Right - formBounds.Right,
                                                 location.Y + screenBounds.Bottom - formBounds.Bottom);
            }
            break;
        case WM_MOVING:
            Cursor.Clip = _cursorClip;
            break;
    }
    base.WndProc(ref m);
}