我正试图在我的应用程序中实现一个功能,将光标捕捉到我的场景中的网格边缘。因为它的立场,我有框架采取当前MouseMove提供e。位置并转换为我的世界坐标并返回屏幕-值匹配。参见下面的基本代码概述。
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);
}
c#是否支持API中的任何东西来捕获MouseMove在它实际移动光标之前,或者我应该只是考虑实现我自己的Cursor类来隐藏Form。光标,只是渲染我的(别的东西,我需要看看,因为我没有线索的功能)。 要对齐边框,请预留一点空间,例如2像素:
if (world.X - 2 < Grid.Left) world.x = Grid.Left;
将光标限制在控件的矩形内,例如:button
Cursor.Clip = aButton.RectangleToScreen(aButton.ClientRectangle);
释放游标:
Cursor.Clip = null;
使用线性外推计算进入帧前的最后一个像素。你需要两个点P1和P2。进入前的点P0可近似为
P0.X = P2.X - P1.X
P0.Y = P2.Y - P1.Y
你可以创建一个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
}
从那里你可以想出逻辑来预测鼠标进入场景
因此,在仔细研究了一天之后,我最终只是分解并编写了一个Cursor类。这里重要的是,我正在使用Managed DirectX在PictureBox中渲染,所以我有一个出路。
有效地,我隐藏了系统。光标当它进入控件并开始通过获取System的偏移量来呈现我自己的光标时。光标在每一帧之间,应用我的逻辑,并确定我想要渲染"我的"光标的位置。看看下面我如何处理offset: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/Form_Closed鼠标移动(MouseMoving/MouseMove) -但又一次,System。光标可能不打算被应用程序操作,以免影响其正常运行的用户体验,因此限制了API中的操作功能。
我仍然愿意接受任何可以让我使用这个系统的建议。游标…