如何知道鼠标将在MouseMove之前的位置

本文关键字:位置 MouseMove 何知道 鼠标 | 更新日期: 2023-09-27 18:02:35

我正试图在我的应用程序中实现一个功能,将光标捕捉到我的场景中的网格边缘。因为它的立场,我有框架采取当前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。光标,只是渲染我的(别的东西,我需要看看,因为我没有线索的功能)。

如何知道鼠标将在MouseMove之前的位置

要对齐边框,请预留一点空间,例如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中的操作功能。

我仍然愿意接受任何可以让我使用这个系统的建议。游标…