2013-03-07 65 views
0

我試圖在我的應用程序中實現一個功能,將光標捕捉到場景中的網格邊緣。現在,我確實有框架採取當前MouseMove提供e.Location並轉換到我的世界座標和回到屏幕 - 和值相匹配。請參閱以下基本代碼概述。如何知道MouseMove之前的鼠標位置

public void Scene_MouseMove(object sender, MouseEventArgs e) 
{ 
    Vector2 world = ScreenToWorld(e.Location); 

    ---> Check here to make sure the world coordinates returned 
     fall inside my grid scene edges. 
    if (world.X < Grid.Left) world.x = Grid.Left; 

    Point target = WorldToScreen(world); 

    // set cursr desired position 
    Cursor.Position = (sender as PictureBox).PointToScreen(target); 
} 

我遇到的問題是,MouseMove事件獲取調用的事實是鼠標在移動,所以,當我打我的網格的邊我看到鼠標的過沖一幀,然後糾正自己。這會導致光標在我移動鼠標時抖動。我想這樣做,當我碰到邊緣時,光標停在它的軌道上,但我不知道如何在鼠標移動之前捕捉數據!

也許我正在談論這個錯誤,所以任何建議將不勝感激。

僅供參考 - 這是我試圖實現的SnapToGrid功能的第一部分。

編輯:一個簡單的例子:

你可以看到運行我的問題下面的簡單的例子。注意當你移動它時,光標是如何閃爍每一幀的?

bool g_Set = false; 
public void Scene_MouseMove(object sender, MouseEventArgs e) 
{ 
    // stop MouseMove from flooding the control recursively 
    if(g_Set) { g_Set = false; return; } 
    g_Set = true; 
    Cursor.Position = new Point(400,400); 
} 

在API中不支持C#什麼來捕捉的MouseMove它實際上移動光標之前,還是應該我只是尋找到實現我自己的Cursor類隱藏Form.Cursor,只是渲染礦(我還需要查看其他內容,因爲我對該功能沒有任何線索)。

+0

如果這是WPF,你可能想看看[這個答案](HTTP://計算器。 com/questions/850956/how-to-limit-cursor-movement-in-wpf-based-app) – 2013-03-07 03:33:21

+0

您是否想將光標剪輯到窗口? http://msdn.microsoft.com/en-us/library/system.windows.forms.cursor.clip.aspx。另請參閱http://stackoverflow.com/q/15029274/56778 – 2013-03-07 03:46:25

+0

如果這是WinForms,則「捕獲」屬性(可從任何地方爲您提供鼠標事件)可能會有所幫助。 – RoadBump 2013-03-07 04:07:25

回答

0

捕捉到邊緣的給一點餘地卡扣,例如2個像素:

if (world.X - 2 < Grid.Left) world.x = Grid.Left; 

以限制光標的控制的矩形內,例如:A按鈕

Cursor.Clip = aButton.RectangleToScreen(aButton.ClientRectangle); 

要釋放光標:

Cursor.Clip = null; 
+0

謝謝傑里米。我已經嘗試了網格大小的緩衝方法。問題在於它只會延遲抖動,因爲光標已經渲染了該幀。我會讀到你說過的剪輯想法,看看我是否可以利用它來做我想做的事情(想象一個更大的PictureBox中的Rectangle--因爲我不想剪輯到實際的控件)。 – Bob2u 2013-03-07 06:17:33

0

使用線性外推到計算進入幀之前的最後一個像素。你需要兩點P1和P2。進入,P0點之前,可以通過

P0.X = P2.X - P1.X 
P0.Y = P2.Y - P1.Y 
+0

已注意。因此,讓我們說我有最後的光標位置和通過當前MouseMove調用e.Location新的位置。現在對Cursor.Position做任何修改還爲時過晚,因爲它已經渲染了該幀。我需要在Windows將其應用於光標以進行調整之前獲得「Delta」更改,並且我不知道下一次MouseMove調用時Cursor「將」更改的單位數。 – Bob2u 2013-03-07 06:14:08

0

近似您可以創建一個UserControl其上有一個場景。將場景放置在中心,並在其周圍具有已知大小的邊距。該UserControl.BackColor = Transparent。處理事件

private void UserControl_MouseMove(Object sender,MouseEventArgs e) 
{ 
    // check if mouse is entering the Scene, you know the size of the margin 
} 

從那裏你可以想出預測鼠標進入場景的邏輯。

0

因此,經過一段美好的一天,我終於找到了一個光標班。這裏重要的是我使用託管DirectX在PictureBox中渲染,所以我找到了出路。

有效地,我隱藏System.Cursor當它進入控制,並開始通過取各幀之間的System.Cursor的偏移量,將我的邏輯,以及確定呈現自己的光標,我想渲染「我的「光標。請參閱下面我處理如何抵消:

public bool g_RecalcCursor = false; 
public Point g_Reference = new Point(400,400); 
public void SceneView_MouseMove(object sender, MouseEventArgs e) 
{ 
    // this logic avoids recursive calls into MouseMove 
    if (g_RecalcCursor) 
    { 
     g_RecalcCursor = false; 
     return; 
    } 

    Point ee = (sender as PictureBox).PointToScreen(e.Location); 
    Point delta = new Point(g_Reference.X - ee.X, g_Reference.Y - ee.Y); 

    //------------------------------------------// 
    // I can use delta now to move my cursor // 
    // and apply logic "BEFORE" it renders  // 
    //------------------------------------------// 

    g_RecalcCursor = true; 
    Cursor.Position = g_Reference; 
} 

我很驚訝的是,有像Form_Closing/對鼠標移動(MouseMoving/的MouseMove)Form_Closed沒有電話 - 但話又說回來,系統。光標可能並不意味着被應用程序操縱,以便不會惡化用戶體驗應用程序的正常運行方式,因此API中的操作功能有限。

我仍然是開放的,它可以讓我用System.Cursor任何建議...

相關問題