2012-07-21 5 views
0

일부 조건이 발생하면 마우스 움직임을 방지하는 방법을 찾고 있습니다.방향 별 마우스 이동 방지

나에게 너무 늦기 때문에 OnMouseMove 이벤트에 대한 작업을 원하지 않습니다.

Cursor.Clip 속성과 같은 것이 필요합니다. 마우스 이동 방향을 비활성화 할 수있는 API가 있습니까? 일종의 ApiMouse.DisableMovement (Directio.Up | Direction.Down | Direction.Left | Direction.Right)?

+4

왜 전 세계 사용자가 그런 식으로 좌절시키고 싶습니까? –

답변

1

. 수락 된 응답의 코드는 창을 바탕 화면 외부로 이동할 수 없도록합니다. 이제 사용자가 드래그하는 동안 커서를 창에 "고정"하려고합니다. 따라서 창을 더 이상 이동할 수 없으면 커서도 더 이상 움직여서는 안됩니다.

질문에 대한 나의 이해가 정확하다면 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); 
} 
+0

그것은 거의 완벽한 솔루션입니다. 그러나 여전히 문제가 있습니다 : 폼을 옮길 때 솔루션을 사용하면 taskbar 뒤에 숨길 수 있으므로이 작업을 원하지 않습니다. taskBar 위치가 바닥에 있고 높이 값이 10이라고 가정하면 어떻게 코드를 수정할 수 있습니까? 그것은 가능한가? – bit

+0

예.나는 스스로에게 대답한다. 마지막 값을 변경하는 것만으로 간단히 가능하다. 예를 들면 .. location.Y + screenBounds.Bottom - formBounds.Bottom + valueOfTaskBarIfItIsBottom). 고맙습니다. 마침내, 나는 모든 것을 해결했습니다! 고맙습니다!!!!! – bit

1

OnMouseMove을 재정의하는 것이 좋지 않으면 WndProc을 무시하는 것이 좋습니다. 마우스로 움직이는 메시지를 "캐치 (Catch)"하여 규칙에 맞는 메시지를 버립니다. 이것은 내가 아는 가장 빠른 방법입니다.

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); 
} 
사용 LParam

WParam 당신에게 마우스의 현재 상태에 대한 자세한 정보를 제공합니다. 더 나은 이해를 위해 this을 확인하십시오.

편집 마우스의 좌표를 얻으려면 question.을 확인하십시오. 그것은 나타냅니다 : 당신이 이전 질문 "Form move inside client desktop area" 참조 이전의 대답에 코멘트에서

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

완벽 해요!. l과 w - params에 대한 예제를 알려주시겠습니까? – bit

+0

@bit 편집 .... –

+0

NOOOO !! 미안하지만 그것은 winform 영역에서 마우스 (사전) 이동만을위한 작업입니다. 대신이 이벤트를 전역 이벤트로 관리해야합니다. – bit