0

I'm looking for a way to prevent mouse movement if my some condition has occurs.

Note that I don't want work over OnMouseMove event because it's too late for me.

I need something like Cursor.Clip property. Is there any API capable of disable some mouse move direction? A sort of ApiMouse.DisableMovement(Directio.Up | Direction.Down | Direction.Left | Direction.Right) ?

bit
  • 934
  • 1
  • 11
  • 32

2 Answers2

1

If you don't like overriding OnMouseMove, then you will probably like overriding WndProc. "Catch" the window mouse-moving messages and discard them accurding to your rules. This is the fastest way I know.

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);
}

Use LParam and WParam to provide you more information about current state of the mouse. Check this for better understanding.

EDIT TO get the coordinates of mouse, check this question.. It indicates that:

int x = msg.LParam.ToInt32() & 0x0000FFFF;
int y = (int)((msg.LParam.ToInt32() & 0xFFFF0000) >> 16)
Point pos = new Point(x, y);
Community
  • 1
  • 1
  • It's perfect!. can you provide me some example for l and w - params? – bit Jul 21 '12 at 21:44
  • NOOOO!! I'm sorry but that's work only for mouse (pre) move in winform area, instead I need to manage this event as globally event. – bit Jul 21 '12 at 22:16
  • @bit How? You need to fire event for example? –  Jul 21 '12 at 22:22
  • I've a form that cannot going off screen. Well, this work is accomplished by managing WndProc Messages (http://stackoverflow.com/questions/11531088/form-move-inside-client-desktop-area). I'd like, when maxPosition is reached, to prevent mouse move over my form. How can I do this? – bit Jul 21 '12 at 22:48
  • I want only this: my form cannot go offscreen. If my form has reached off limit (for instance, top-right desktop corner) then mouse cannot go over more too, but surely it can go in all other directions. ..help.. – bit Jul 22 '12 at 00:18
1

In a comment to a previous answer you refer to your previous Question "Form move inside client desktop area". The code in the accepted answer prevents the window to be moved outside the desktop. And now you want to "pin" the cursor to the window while the user is dragging it. So if the window cannot be moved further the cursor also should not go further.

If my understanding of your question is correct you should handle the WM_NCLBUTTONDOWN message to calculate the limits for the mouse movement. You can then use Cursor.Clip to apply these limits.

However, if you apply the clip rectangle in the WM_NCLBUTTONDOWN message it will be removed immediately. If you apply it in the WM_MOVING message instead it will be automatically removed when the dragging ends.

This is then also a solution to the aforementioned question: If the mouse can only be moved in the calculated rectangle while the user is dragging the window then the window itself can only be moved in the allowed region.

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);
}
Community
  • 1
  • 1
pescolino
  • 3,086
  • 2
  • 14
  • 24
  • It's almost the perfect solution, however I've still an issue: with your solution when I move the form I'm be able to hide it behind taskBar and I don't want this. Supposing taskBar location is on bottom and its height value is 10, how can I modify you code? Is it possibile? – bit Jul 22 '12 at 07:10
  • Yes. I answer myself, it it possible simply by change last value, for instance: .. location.Y + screenBounds.Bottom - formBounds.Bottom + valueOfTaskBarIfItIsBottom). Thank you very much. At last, I've solved all things! Thank You!!!!! – bit Jul 22 '12 at 07:20