How to make mouse movement work with no delay?

2019-05-11 22:58发布

I'm making a program that let me click on the center of two concentric circles and, by mouse move, change it's position and i can do the same with it's radii. The thing is that the mouse movement is followed by a delay response from the circles drawing making the radius follow the mouse instead of being exactly in the same position during the movement.

Would you guys know how to make it work like that? pin point following by the drawing.

a bit of the code that treats the mouse clicking and movements:

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
2条回答
走好不送
2楼-- · 2019-05-11 23:44

i've found a solution to that problem!

It's way simple than expected, all you got to do is add a flag while creating the render target, that way the mousemove will respond way faster: the flag is: 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
            );
查看更多
\"骚年 ilove
3楼-- · 2019-05-11 23:47

According to MSDN ( http://msdn.microsoft.com/en-us/library/dd145002%28v=vs.85%29.aspx ) InvalidateRect doesn’t cause the window to be repainted until the next WM_PAINT and "The system sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window." so it’s not immediate.

I found a possible solution on MSDN here Drawing Without the WM_PAINT Message

查看更多
登录 后发表回答