如何使鼠标移动不延迟

How to make mouse movement work with no delay?

本文关键字:延迟 移动 鼠标 何使      更新时间:2023-10-16

我正在制作一个程序,让我点击两个同心圆的中心,通过鼠标移动,改变它的位置,我可以对它的半径做同样的事情。问题是,鼠标移动后会出现圆圈绘制的延迟响应,使半径跟随鼠标移动,而不是在移动过程中完全处于相同的位置。

你们知道如何让它像那样工作吗?图形后面的接点。

处理鼠标点击和移动的一些代码:

void DemoApp::OnLButtonDown(FLOAT pixelX, FLOAT pixelY)
{
    SetCapture(m_hwnd);
    mouseRegion = DPIScale::PixelsToDips(pixelX, pixelY);
    FLOAT xDifference = centerCircles.x - mouseRegion.x;
    FLOAT yDifference = centerCircles.y - mouseRegion.y;
    FLOAT distanceToCenter = sqrtf(xDifference*xDifference + yDifference*yDifference);
    if(distanceToCenter < 10.0f)
    {
        centerMove = true;
        minimumRadiusCircleMove = false;
        maximumRadiusCircleMove = false;
    }
    else if((distanceToCenter > (minimumRadius - 1.0f)) && (distanceToCenter < (minimumRadius + 1.0f)))
    {
        minimumRadiusCircleMove = true;
        centerMove = false;
        maximumRadiusCircleMove = false;
    }
    else if((distanceToCenter > (maximumRadius - 1.0f)) && (distanceToCenter < (maximumRadius + 1.0f)))
    {
        maximumRadiusCircleMove = true;
        centerMove = false;
        minimumRadiusCircleMove = false;
    }
    else
    {
        centerMove = false;
        minimumRadiusCircleMove = false;
        maximumRadiusCircleMove = false;
    }

    InvalidateRect(m_hwnd, NULL, FALSE);
}
void DemoApp::OnMouseMove(int pixelX, int pixelY, DWORD flags)
{
    if (flags & MK_LBUTTON) 
    { 
        if(centerMove)
        {
            centerCircles = DPIScale::PixelsToDips(pixelX, pixelY);
            FLOAT distanceLeftToCenterCircles = abs(centerCircles.x - bitmapTopLeft);
            FLOAT distanceTopToCenterCircles = abs(centerCircles.y - bitmapTopRight);
            percentageFromLeft = distanceLeftToCenterCircles / displaySizeWidth;
            percentageFromTop = distanceTopToCenterCircles / displaySizeHeight;
        }
        else if(minimumRadiusCircleMove)
        {
            radiusSelection = DPIScale::PixelsToDips(pixelX, pixelY);
            FLOAT xDifference = centerCircles.x - radiusSelection.x;
            FLOAT yDifference = centerCircles.y - radiusSelection.y;
            minimumRadius = sqrtf(xDifference*xDifference + yDifference*yDifference);
            minimumRadiusPercentage = minimumRadius/(displaySizeWidth/2);
        }
        else if(maximumRadiusCircleMove)
        {
            radiusSelection = DPIScale::PixelsToDips(pixelX, pixelY);
            FLOAT xDifference = centerCircles.x - radiusSelection.x;
            FLOAT yDifference = centerCircles.y - radiusSelection.y;
            maximumRadius = sqrtf(xDifference*xDifference + yDifference*yDifference);
            maximumRadiusPercentage = maximumRadius/(displaySizeWidth/2);
        }
        InvalidateRect(m_hwnd, NULL, FALSE);
    }
}
void DemoApp::OnLButtonUp()
{
    ReleaseCapture(); 
}

根据MSDN(http://msdn.microsoft.com/en-us/library/dd145002%28v=vs.85%29.aspx)InvalidateRect不会导致窗口在下一个WM_PAINT之前被重新绘制,并且"只要窗口的更新区域不为空,并且该窗口的应用程序队列中没有其他消息,系统就会向该窗口发送WM_PAINT消息。"因此它不是立即的。

我在MSDN上找到了一个可能的解决方案,这里是Drawing Without the WM_PAINT Message

我找到了这个问题的解决方案!

这比预期的要简单得多,您所要做的就是在创建渲染目标时添加一个标志,这样鼠标移动的响应速度就会更快:标志为:D2D1_PRESENT_OPTIONS_IMEDIATELY。

// Create Direct2d render target.
        hr = m_pD2DFactory->CreateHwndRenderTarget(
            D2D1::RenderTargetProperties(),
            D2D1::HwndRenderTargetProperties(m_hwnd, size, D2D1_PRESENT_OPTIONS_IMMEDIATELY),
            &m_pRenderTarget
            );