2012-07-21 110 views
0

我正在尋找一種方法來防止鼠標移動,如果我的一些條件已經發生。防止鼠標移動的方向

請注意,我不想在OnMouseMove事件上工作,因爲對我而言已經太遲了。

我需要類似Cursor.Clip屬性。有沒有API可以禁用某些鼠標移動方向?一種ApiMouse.DisableMovement(Directio.Up | Direction.Down | Direction.Left | Direction.Right)?

+4

爲什麼在這個世界上你會想要挫敗你的用戶呢? – 2012-07-21 21:10:14

回答

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

它幾乎是一個完美的解決方案,但是我仍然有一個問題:當我移動窗體時,我可以將它隱藏在taskBar後面,而我不想要這個。假設任務欄位置在底部,其高度值爲10,我如何修改你的代碼?它可能嗎? – bit 2012-07-22 07:10:10

+0

是的。我回答自己,它可以簡單地通過改變最後的值,例如:.. location.Y + screenBounds.Bottom - formBounds.Bottom + valueOfTaskBarIfItIsBottom)。非常感謝你。最後,我解決了所有問題!謝謝!!!!! – bit 2012-07-22 07:20:10

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); 
+0

這是完美的!你能給我一些例子嗎? – bit 2012-07-21 21:44:58

+0

@bit編輯... – 2012-07-21 21:52:32

+0

NOOOO !!我很抱歉,但這隻適用於winform區域中的鼠標(前)移動,相反我需要將此事件作爲全局事件來管理。 – bit 2012-07-21 22:16:19