Как заставить движение мыши работать без задержки? - PullRequest
3 голосов
/ 30 января 2012

Я создаю программу, которая позволяет мне щелкать по центру двух концентрических окружностей и, перемещая мышь, изменять его положение, и я могу сделать то же самое с его радиусами.Дело в том, что за движением мыши следует ответ задержки из рисунка окружности, заставляющий радиус следовать за мышью, а не находиться точно в том же положении во время движения.

Ребята, знаете ли вы, как заставить это работать?как это?Точка, следующая за рисунком.

немного кода, который обрабатывает щелчки и движения мыши:

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

Ответы [ 2 ]

2 голосов
/ 30 января 2012

Согласно MSDN (http://msdn.microsoft.com/en-us/library/dd145002%28v=vs.85%29.aspx) InvalidateRect не приводит к перерисовке окна до следующего WM_PAINT и «Система отправляет сообщение WM_PAINT в окно всякий раз, когда его область обновления не пуста и нет другие сообщения в очереди приложений для этого окна. " так что это не сразу.

Я нашел возможное решение для MSDN здесь Рисование без сообщения WM_PAINT

1 голос
/ 14 марта 2012

Я нашел решение этой проблемы!

Это намного проще, чем ожидалось, все, что вам нужно сделать, это добавить флаг при создании цели рендеринга, чтобы движение мыши реагировало намного быстрее:флаг: 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
            );
...