Reputation: 963
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) ?
Upvotes: 0
Views: 2019
Reputation: 3123
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);
}
Upvotes: 1
Reputation:
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);
Upvotes: 1