【问题标题】:How to make mouse movement work with no delay?如何使鼠标移动无延迟?
【发布时间】:2012-03-14 23:53:48
【问题描述】:

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

你们知道如何让它像这样工作吗?紧跟在图纸后面。

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

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(); 
}

【问题讨论】:

    标签: c++ direct2d


    【解决方案1】:

    根据 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

    【讨论】:

    • 不只是WM_PAINT,WM_MOUSEMOVE只有在消息队列无事可做时才发送。双重打击。
    • 我调用了渲染函数来重绘屏幕,所以它在 direct2d 上而不是在 GDI 上获得了t need to call WM_PAINT from the mousemove function but that made no difference. Since im 我无法使用 HDC。还有什么想法吗?感谢您的努力。
    【解决方案2】:

    我已经找到了解决这个问题的方法!

    这比想象的要简单,你所要做的就是在创建渲染目标时添加一个标志,这样 mousemove 会更快地响应: 标志是:D2D1_PRESENT_OPTIONS_IMMEDIATELY。

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

    【讨论】:

      猜你喜欢
      • 2018-07-06
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-23
      • 2020-04-07
      相关资源
      最近更新 更多